Cataclysm BN
map Class Reference

Manage and cache data about a part of the map. More...

#include <map.h>

Inheritance diagram for map:
tinymap fake_map

Classes

struct  apparent_light_info
 

Public Member Functions

 map (int mapsize=MAPSIZE, bool zlev=false)
 
 map (bool zlev)
 
virtual ~map ()
 
mapoperator= (const map &)=delete
 
mapoperator= (map &&)
 
void set_transparency_cache_dirty (const int zlev)
 Sets a dirty flag on the a given cache. More...
 
void set_transparency_cache_dirty (const tripoint &p)
 
void set_seen_cache_dirty (const tripoint change_location)
 
void set_seen_cache_dirty (const int zlevel)
 
void set_outside_cache_dirty (const int zlev)
 
void set_floor_cache_dirty (const int zlev)
 
void set_suspension_cache_dirty (const int zlev)
 
void set_pathfinding_cache_dirty (int zlev)
 
void set_memory_seen_cache_dirty (const tripoint &p)
 
void invalidate_map_cache (const int zlev)
 
bool check_seen_cache (const tripoint &p) const
 
bool check_and_set_seen_cache (const tripoint &p) const
 
void on_vehicle_moved (int smz)
 Callback invoked when a vehicle has moved. More...
 
lit_level apparent_light_at (const tripoint &p, const visibility_variables &cache) const
 Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc. More...
 
visibility_type get_visibility (lit_level ll, const visibility_variables &cache) const
 
std::tuple< maptile, maptile, maptileget_wind_blockers (const int &winddirection, const tripoint &pos)
 
void draw (const catacurses::window &w, const tripoint &center)
 Draw a visible part of the map into w. More...
 
void drawsq (const catacurses::window &w, const tripoint &p, const drawsq_params &params) const
 Draw the map tile at the given coordinate. More...
 
void save ()
 Add currently loaded submaps (in grid) to the mapbuffer. More...
 
void load (const tripoint &w, bool update_vehicles, bool pump_events=false)
 Load submaps into grid. More...
 
void load (const tripoint_abs_sm &w, bool update_vehicles, bool pump_events=false)
 
void shift (point s)
 Shift the map along the vector s. More...
 
void vertical_shift (int newz)
 Moves the map vertically to (not by!) newz. More...
 
void clear_spawns ()
 
void clear_traps ()
 
maptile maptile_at (const tripoint &p) const
 
maptile maptile_at (const tripoint &p)
 
int move_cost (const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
 Calculate the cost to move past the tile at p. More...
 
int move_cost (point p, const vehicle *ignored_vehicle=nullptr) const
 
bool impassable (const tripoint &p) const
 
bool impassable (point p) const
 
bool passable (const tripoint &p) const
 
bool passable (point p) const
 
bool is_wall_adjacent (const tripoint &center) const
 
int move_cost_ter_furn (const tripoint &p) const
 Similar behavior to move_cost(), but ignores vehicles. More...
 
int move_cost_ter_furn (point p) const
 
bool impassable_ter_furn (const tripoint &p) const
 
bool passable_ter_furn (const tripoint &p) const
 
int combined_movecost (const tripoint &from, const tripoint &to, const vehicle *ignored_vehicle=nullptr, int modifier=0, bool flying=false, bool via_ramp=false) const
 Cost to move out of one tile and into the next. More...
 
bool valid_move (const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
 Returns true if a creature could walk from from to to in one step. More...
 
double ranged_target_size (const tripoint &p) const
 Size of map objects at p for purposes of ranged combat. More...
 
bool sees (const tripoint &F, const tripoint &T, int range) const
 Returns whether F sees T with a view range of range. More...
 
int obstacle_coverage (const tripoint &loc1, const tripoint &loc2) const
 Returns coverage of target in relation to the observer. More...
 
int coverage (const tripoint &p) const
 Returns coverage value of the tile. More...
 
bool clear_path (const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
 Check whether there's a direct line of sight between F and T with the additional movecost restraints. More...
 
bool obstructed_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent. More...
 
bool obscured_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent. More...
 
void reachable_flood_steps (std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
 Populates a vector of points that are reachable within a number of steps from a point. More...
 
std::vector< tripointfind_clear_path (const tripoint &source, const tripoint &destination) const
 Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one. More...
 
bool accessible_items (const tripoint &t) const
 Check whether the player can access the items located . More...
 
std::vector< tripointget_dir_circle (const tripoint &f, const tripoint &t) const
 Calculate next search points surrounding the current position. More...
 
std::vector< tripointroute (const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
 Calculate the best path using A*. More...
 
VehicleList get_vehicles ()
 
void add_vehicle_to_cache (vehicle *)
 
void clear_vehicle_point_from_cache (vehicle *veh, const tripoint &pt)
 
void update_vehicle_cache (vehicle *, int old_zlevel)
 
void reset_vehicle_cache ()
 
void clear_vehicle_cache ()
 
void clear_vehicle_list (int zlev)
 
void update_vehicle_list (const submap *to, int zlev)
 
bool check_vehicle_zones (int zlev)
 
std::vector< zone_data * > get_vehicle_zones (int zlev)
 
void register_vehicle_zone (vehicle *, int zlev)
 
bool deregister_vehicle_zone (zone_data &zone)
 
std::unique_ptr< vehicledetach_vehicle (vehicle *veh)
 
void destroy_vehicle (vehicle *veh)
 
void vehmove ()
 
bool vehproceed (VehicleList &vehicle_list)
 
VehicleList get_vehicles (const tripoint &start, const tripoint &end)
 
optional_vpart_position veh_at (const tripoint &p) const
 Checks if tile is occupied by vehicle and by which part. More...
 
optional_vpart_position veh_at (const tripoint_abs_ms &p) const
 
vehicleveh_at_internal (const tripoint &p, int &part_num)
 
const vehicleveh_at_internal (const tripoint &p, int &part_num) const
 
void board_vehicle (const tripoint &p, player *pl)
 
void unboard_vehicle (const vpart_reference &, Character *passenger, bool dead_passenger=false)
 
void unboard_vehicle (const tripoint &p, bool dead_passenger=false)
 
bool displace_vehicle (vehicle &veh, const tripoint &dp)
 
void shift_vehicle_z (vehicle &veh, int z_shift)
 
bool displace_water (const tripoint &dp)
 
float vehicle_wheel_traction (const vehicle &veh, bool ignore_movement_modifiers=false) const
 
float vehicle_vehicle_collision (vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
 
units::angle shake_vehicle (vehicle &veh, int velocity_before, units::angle direction)
 
vehiclemove_vehicle (vehicle &veh, const tripoint &dp, const tileray &facing)
 
void set (const tripoint &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
void set (point p, const ter_id &new_terrain, const furn_id &new_furniture)
 
std::string name (const tripoint &p)
 
std::string name (point p)
 
std::string disp_name (const tripoint &p)
 
std::string obstacle_name (const tripoint &p)
 Returns the name of the obstacle at p that might be blocking movement/projectiles/etc. More...
 
bool has_furn (const tripoint &p) const
 
bool has_furn (point p) const
 
furn_id furn (const tripoint &p) const
 
furn_id furn (point p) const
 
void furn_set (const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
 Sets the furniture at given position. More...
 
void furn_set (point p, const furn_id &new_furniture)
 
std::string furnname (const tripoint &p)
 
std::string furnname (point p)
 
bool can_move_furniture (const tripoint &pos, player *p=nullptr)
 
ter_id ter (const tripoint &p) const
 
ter_id ter (point p) const
 
uint8_t get_known_connections (const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
 
const harvest_idget_harvest (const tripoint &p) const
 Returns the full harvest list, for spawning. More...
 
const std::set< std::string > & get_harvest_names (const tripoint &p) const
 Returns names of the items that would be dropped. More...
 
ter_id get_ter_transforms_into (const tripoint &p) const
 
furn_id get_furn_transforms_into (const tripoint &p) const
 
bool ter_set (const tripoint &p, const ter_id &new_terrain)
 
bool ter_set (point p, const ter_id &new_terrain)
 
std::string tername (const tripoint &p) const
 
std::string tername (point p) const
 
bool has_nearby_fire (const tripoint &p, int radius=1)
 
bool has_nearby_table (const tripoint &p, int radius=1)
 Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating. More...
 
bool has_nearby_chair (const tripoint &p, int radius=1)
 Check whether a chair or vehicle seat is nearby. More...
 
bool sees_some_items (const tripoint &p, const Creature &who) const
 Check if creature can see some items at p. More...
 
bool sees_some_items (const tripoint &p, const tripoint &from) const
 
bool could_see_items (const tripoint &p, const Creature &who) const
 Check if the creature could see items at p if there were any items. More...
 
bool could_see_items (const tripoint &p, const tripoint &from) const
 
bool has_items (const tripoint &p) const
 Checks for existence of items. More...
 
void examine (Character &p, const tripoint &pos)
 Calls the examine function of furniture or terrain at given tile, for given character. More...
 
bool is_harvestable (const tripoint &pos) const
 Returns true if point at pos is harvestable right now, with no extra tools. More...
 
std::string features (const tripoint &p)
 
std::string features (point p)
 
bool has_flag (const std::string &flag, const tripoint &p) const
 
bool has_flag (const std::string &flag, point p) const
 
bool can_put_items (const tripoint &p) const
 
bool can_put_items (point p) const
 
bool can_put_items_ter_furn (const tripoint &p) const
 
bool can_put_items_ter_furn (point p) const
 
bool has_flag_ter (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter (const std::string &flag, point p) const
 
bool has_flag_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn (const std::string &flag, point p) const
 
bool has_flag_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn_or_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, point p) const
 
bool has_flag (ter_bitflags flag, const tripoint &p) const
 
bool has_flag (ter_bitflags flag, point p) const
 
bool has_flag_ter (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter (ter_bitflags flag, point p) const
 
bool has_flag_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_furn (ter_bitflags flag, point p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, point p) const
 
bool is_bashable (const tripoint &p, bool allow_floor=false) const
 Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p. More...
 
bool is_bashable (point p) const
 
bool is_bashable_ter (const tripoint &p, bool allow_floor=false) const
 Returns true if the terrain at p is bashable. More...
 
bool is_bashable_ter (point p) const
 
bool is_bashable_furn (const tripoint &p) const
 Returns true if the furniture at p is bashable. More...
 
bool is_bashable_furn (point p) const
 
bool is_bashable_ter_furn (const tripoint &p, bool allow_floor=false) const
 Returns true if the furniture or terrain at p is bashable. More...
 
bool is_bashable_ter_furn (point p) const
 
int bash_strength (const tripoint &p, bool allow_floor=false) const
 Returns max_str of the furniture or terrain at p. More...
 
int bash_strength (point p) const
 
int bash_resistance (const tripoint &p, bool allow_floor=false) const
 Returns min_str of the furniture or terrain at p. More...
 
int bash_resistance (point p) const
 
int bash_rating (int str, const tripoint &p, bool allow_floor=false) const
 Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down. More...
 
int bash_rating (const int str, point p) const
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, const ter_id &floor_type, bool overwrite=false)
 Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true. More...
 
void make_rubble (const tripoint &p, const furn_id &rubble_type)
 
void make_rubble (const tripoint &p)
 
bool is_outside (const tripoint &p) const
 
bool is_outside (point p) const
 
bool is_divable (const tripoint &p) const
 Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing). More...
 
bool is_divable (point p) const
 
bool is_water_shallow_current (const tripoint &p) const
 
bool is_water_shallow_current (point p) const
 
bool is_last_ter_wall (bool no_furn, point p, point max, direction dir) const
 Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST. More...
 
bool tinder_at (const tripoint &p)
 Checks if there are any tinder flagged items on the tile. More...
 
bool flammable_items_at (const tripoint &p, int threshold=0)
 Checks if there are any flammable items on the tile. More...
 
bool is_flammable (const tripoint &p)
 Returns true if there is a flammable item or field or the furn/terrain is flammable at p. More...
 
point random_outdoor_tile ()
 
void draw_line_ter (const ter_id &type, point p1, point p2)
 
void draw_line_furn (const furn_id &type, point p1, point p2)
 
void draw_fill_background (const ter_id &type)
 
void draw_fill_background (ter_id(*f)())
 
void draw_fill_background (const weighted_int_list< ter_id > &f)
 
void draw_square_ter (const ter_id &type, point p1, point p2)
 
void draw_square_furn (const furn_id &type, point p1, point p2)
 
void draw_square_ter (ter_id(*f)(), point p1, point p2)
 
void draw_square_ter (const weighted_int_list< ter_id > &f, point p1, point p2)
 
void draw_rough_circle_ter (const ter_id &type, point p, int rad)
 
void draw_rough_circle_furn (const furn_id &type, point p, int rad)
 
void draw_circle_ter (const ter_id &type, const rl_vec2d &p, double rad)
 
void draw_circle_ter (const ter_id &type, point p, int rad)
 
void draw_circle_furn (const furn_id &type, point p, int rad)
 
void add_corpse (const tripoint &p)
 
void translate (const ter_id &from, const ter_id &to)
 
void translate_radius (const ter_id &from, const ter_id &to, float radi, const tripoint &p, bool same_submap=false, bool toggle_between=false)
 
bool close_door (const tripoint &p, bool inside, bool check_only)
 
bool open_door (const tripoint &p, bool inside, bool check_only=false)
 
void batter (const tripoint &p, int power, int tries=1, bool silent=false)
 bash a square for a set number of times at set power. More...
 
void destroy (const tripoint &p, bool silent=false)
 Keeps bashing a square until it can't be bashed anymore. More...
 
void destroy_furn (const tripoint &p, bool silent=false)
 Keeps bashing a square until there is no more furniture. More...
 
void crush (const tripoint &p)
 
void shoot (const tripoint &p, projectile &proj, bool hit_items)
 
int collapse_check (const tripoint &p)
 Checks if a square should collapse, returns the X for the one_in(X) collapse chance. More...
 
void collapse_at (const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
 Causes a collapse at p, such as from destroying a wall. More...
 
void propagate_suspension_check (const tripoint &point)
 Checks surrounding tiles for suspension, and has them check for collapse. More...
 
void collapse_invalid_suspension (const tripoint &point)
 Triggers a recursive collapse of suspended tiles based on their support validity. More...
 
bool is_suspension_valid (const tripoint &point)
 Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid. More...
 
void smash_trap (const tripoint &p, const int power, const std::string &cause_message)
 Tries to smash the trap at the given tripoint. More...
 
void smash_items (const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
 Tries to smash the items at the given tripoint. More...
 
bash_results bash (const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
 Returns a pair where first is whether anything was smashed and second is if it was destroyed. More...
 
bash_results bash_vehicle (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_furn (const tripoint &p, const bash_params &params)
 
bool hit_with_acid (const tripoint &p)
 
bool hit_with_fire (const tripoint &p)
 
bool has_adjacent_furniture_with (const tripoint &p, const std::function< bool(const furn_t &)> &filter)
 Returns true if there is furniture for which filter returns true in a 1 tile radius of p. More...
 
bool mop_spills (const tripoint &p)
 Remove moppable fields/items at this location. More...
 
void decay_fields_and_scent (const time_duration &amount)
 Moved here from weather.cpp for speed. More...
 
std::string get_signage (const tripoint &p) const
 
void set_signage (const tripoint &p, const std::string &message) const
 
void delete_signage (const tripoint &p) const
 
int get_radiation (const tripoint &p) const
 
void set_radiation (const tripoint &p, int value)
 
void set_radiation (point p, const int value)
 
void adjust_radiation (const tripoint &p, int delta)
 Increment the radiation in the given tile by the given delta (decrement it if delta is negative) More...
 
void adjust_radiation (point p, const int delta)
 
int get_temperature (const tripoint &p) const
 
void set_temperature (const tripoint &p, int temperature)
 
void set_temperature (point p, int new_temperature)
 
std::vector< tripointcheck_submap_active_item_consistency ()
 
map_stack i_at (const tripoint &p)
 
map_stack i_at (point p)
 
item water_from (const tripoint &p)
 
void i_clear (const tripoint &p)
 
void i_clear (point p)
 
map_stack::iterator i_rem (const tripoint &p, map_stack::const_iterator it)
 
map_stack::iterator i_rem (point location, map_stack::const_iterator it)
 
void i_rem (const tripoint &p, item *it)
 
void i_rem (point p, item *it)
 
void spawn_artifact (const tripoint &p)
 
void spawn_natural_artifact (const tripoint &p, artifact_natural_property prop)
 
void spawn_item (const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (point p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const tripoint &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (point p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
units::volume max_volume (const tripoint &p)
 
units::volume free_volume (const tripoint &p)
 
units::volume stored_volume (const tripoint &p)
 
itemadd_item_or_charges (const tripoint &pos, item obj, bool overflow=true)
 Adds an item to map tile or stacks charges. More...
 
itemadd_item_or_charges (point p, item obj, bool overflow=true)
 
itemadd_item (const tripoint &p, item new_item)
 Place an item on the map, despite the parameter name, this is not necessarily a new item. More...
 
void add_item (point p, item new_item)
 
itemspawn_an_item (const tripoint &p, item new_item, int charges, int damlevel)
 
void spawn_an_item (point p, item new_item, int charges, int damlevel)
 
void make_active (item_location &loc)
 Update an item's active status, for example when adding hot or perishable liquid to a container. More...
 
void update_lum (item_location &loc, bool add)
 Update luminosity before and after item's transformation. More...
 

Static Public Member Functions

static apparent_light_info apparent_light_helper (const level_cache &map_cache, const tripoint &p)
 Helper function for light claculation; exposed here for map editor. More...
 

Private Member Functions

maptile maptile_at_internal (const tripoint &p) const
 
maptile maptile_at_internal (const tripoint &p)
 
std::pair< tripoint, maptilemaptile_has_bounds (const tripoint &p, bool bounds_checked)
 
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors (const tripoint &p)
 
void spread_gas (field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
 
void create_hot_air (const tripoint &p, int intensity)
 
bool gas_can_spread_to (field_entry &cur, const tripoint &src, const tripoint &dst)
 
void gas_spread_to (field_entry &cur, maptile &dst, const tripoint &p)
 
int burn_body_part (player &u, field_entry &cur, body_part bp, int scale)
 
bool sees (const tripoint &F, const tripoint &T, int range, int &bresenham_slope) const
 Don't expose the slope adjust outside map functions. More...
 

Friends

class editmap
 
class visitable< map_cursor >
 

Consume items on the map

The functions here consume accessible items / item charges on the map or in vehicles around the player (whose positions is given as origin).

They return a list of copies of the consumed items (with the actually consumed charges in it). The quantity / amount parameter will be reduced by the number of items/charges removed. If all required items could be removed from the map, the quantity/amount will be 0, otherwise it will contain a positive value and the remaining items must be gathered from somewhere else.

enum  iteration_state { ITER_CONTINUE = 0 , ITER_SKIP_SUBMAP , ITER_SKIP_ZLEVEL , ITER_FINISH }
 Enum used by functors in function_over to control execution. More...
 
std::set< tripointsupport_cache_dirty
 
std::vector< submap * > grid
 The list of currently loaded submaps. More...
 
std::vector< std::vector< tripoint > > traplocs
 This vector contains an entry for each trap type, it has therefor the same size as the traplist vector. More...
 
std::vector< tripointfield_furn_locs
 Vector of tripoints containing active field-emitting furniture. More...
 
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERScaches
 Holds caches for visibility, light, transparency and vehicles. More...
 
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERSpathfinding_caches
 
std::set< tripointsubmaps_with_active_items
 Set of submaps that contain active items in absolute coordinates. More...
 
lru_cache< point, char > skew_vision_cache
 Cache of coordinate pairs recently checked for visibility. More...
 
VehicleList last_full_vehicle_list
 Vehicle list doesn't change often, but is pretty expensive. More...
 
bool last_full_vehicle_list_dirty = true
 
visibility_variables visibility_variables_cache
 
std::optional< std::pair< tripoint, int > > max_populated_zlev = std::nullopt
 
std::set< vehicle * > dirty_vehicle_list
 
int my_MAPSIZE
 
bool zlevels
 
vision_adjustment vision_transparency_cache [8] = { VISION_ADJUST_NONE }
 
tripoint abs_sub
 Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation). More...
 
std::list< itemuse_amount_square (const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_amount (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_charges (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 Place items from item group in the rectangle f - t. More...
 
std::vector< item * > place_items (const item_group_id &loc, int chance, point p1, point p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 
std::vector< item * > put_items_from_loc (const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
 Place items from an item group at p. More...
 
std::vector< item * > spawn_items (const tripoint &p, const std::vector< item > &new_items)
 
void spawn_items (point p, const std::vector< item > &new_items)
 
void create_anomaly (const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
 
void create_anomaly (point cp, artifact_natural_property prop, bool create_rubble=true)
 
void partial_con_set (const tripoint &p, const partial_con &con)
 
void partial_con_remove (const tripoint &p)
 
partial_conpartial_con_at (const tripoint &p)
 
void trap_set (const tripoint &p, const trap_id &type)
 
const traptr_at (const tripoint &p) const
 
bool can_see_trap_at (const tripoint &p, const Character &c) const
 See trap::can_see, which is called for the trap here. More...
 
void disarm_trap (const tripoint &p)
 
void remove_trap (const tripoint &p)
 
const std::vector< tripoint > & get_furn_field_locations () const
 
const std::vector< tripoint > & trap_locations (const trap_id &type) const
 
void create_burnproducts (const tripoint &p, const item &fuel, const units::mass &burned_mass)
 
void process_fields ()
 
void process_fields_in_submap (submap *current_submap, const tripoint &submap_pos)
 
void creature_in_field (Creature &critter)
 Apply field effects to the creature when it's on a square with fields. More...
 
void creature_on_trap (Creature &critter, bool may_avoid=true)
 Apply trap effects to the creature, similar to creature_in_field. More...
 
const fieldfield_at (const tripoint &p) const
 Get the fields that are here. More...
 
fieldfield_at (const tripoint &p)
 Gets fields that are here. More...
 
time_duration get_field_age (const tripoint &p, const field_type_id &type) const
 Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns. More...
 
int get_field_intensity (const tripoint &p, const field_type_id &type) const
 Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0. More...
 
time_duration mod_field_age (const tripoint &p, const field_type_id &type, const time_duration &offset)
 Increment/decrement age of field entry at point. More...
 
int mod_field_intensity (const tripoint &p, const field_type_id &type, int offset)
 Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
time_duration set_field_age (const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
 Set age of field entry at point. More...
 
int set_field_intensity (const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
 Set intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
field_entryget_field (const tripoint &p, const field_type_id &type)
 Get field of specific type at point. More...
 
bool dangerous_field_at (const tripoint &p)
 
bool add_field (const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
 Add field entry at point, or set intensity if present. More...
 
void remove_field (const tripoint &p, const field_type_id &field_to_remove)
 Remove field entry at xy, ignored if the field entry is not present. More...
 
void add_splatter (const field_type_id &type, const tripoint &where, int intensity=1)
 
void add_splatter_trail (const field_type_id &type, const tripoint &from, const tripoint &to)
 
void add_splash (const field_type_id &type, const tripoint &center, int radius, int intensity)
 
void propagate_field (const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
 
void emit_field (const tripoint &pos, const emit_id &src, float mul=1.0f)
 Runs one cycle of emission src which may result in propagation of fields. More...
 
void scent_blockers (std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &scent_transfer, point min, point max)
 Build the map of scent-resistant tiles. More...
 
computercomputer_at (const tripoint &p)
 
computeradd_computer (const tripoint &p, const std::string &name, int security)
 
void add_camp (const tripoint_abs_omt &omt_pos, const std::string &name)
 
void remove_submap_camp (const tripoint &)
 
basecamp hoist_submap_camp (const tripoint &p)
 
bool point_within_camp (const tripoint &point_check) const
 
bool has_graffiti_at (const tripoint &p) const
 
const std::string & graffiti_at (const tripoint &p) const
 
void set_graffiti (const tripoint &p, const std::string &contents)
 
void delete_graffiti (const tripoint &p)
 
int climb_difficulty (const tripoint &p) const
 Checks 3x3 block centered on p for terrain to climb. More...
 
bool has_floor (const tripoint &p) const
 
bool floor_between (const tripoint &first, const tripoint &second) const
 Checks if there's a floor between the two tiles. More...
 
bool supports_above (const tripoint &p) const
 Does this tile support vehicles and furniture above it. More...
 
bool has_floor_or_support (const tripoint &p) const
 
void drop_everything (const tripoint &p)
 Handles map objects of given type (not creatures) falling down. More...
 
void drop_furniture (const tripoint &p)
 
void drop_items (const tripoint &p)
 
void drop_vehicle (const tripoint &p)
 
void drop_fields (const tripoint &p)
 
void process_falling ()
 Invoked drop_everything on cached dirty tiles. More...
 
bool is_cornerfloor (const tripoint &p) const
 
void generate (const tripoint &p, const time_point &when)
 
void place_spawns (const mongroup_id &group, int chance, point p1, point p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
 
void place_gas_pump (point p, int charges, const std::string &fuel_type)
 
void place_gas_pump (point p, int charges)
 
void place_toilet (point p, int charges=6 *4)
 
void place_vending (point p, const item_group_id &type, bool reinforced=false)
 
character_id place_npc (point p, const string_id< npc_template > &type, bool force=false)
 
void apply_faction_ownership (point p1, point p2, const faction_id &id)
 
void add_spawn (const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
 
void do_vehicle_caching (int z)
 
void build_map_cache (int zlev, bool skip_lightmap=false)
 
void build_obstacle_cache (const tripoint &start, const tripoint &end, float(&obstacle_cache)[MAPSIZE_X][MAPSIZE_Y])
 
vehicleadd_vehicle (const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vgroup_id &type, point p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, point p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
float light_transparency (const tripoint &p) const
 
lit_level light_at (const tripoint &p) const
 
float ambient_light_at (const tripoint &p) const
 
bool is_transparent (const tripoint &p) const
 Returns whether the tile at p is transparent(you can look past it). More...
 
bool pl_sees (const tripoint &t, int max_range) const
 Whether the player character (g->u) can see the given square (local map coordinates). More...
 
bool pl_line_of_sight (const tripoint &t, int max_range) const
 Uses the map cache to tell if the player could see the given square. More...
 
tripoint get_abs_sub () const
 return abs_sub More...
 
tripoint getabs (const tripoint &p) const
 Translates local (to this map) coordinates of a square to global absolute coordinates. More...
 
tripoint_abs_ms getglobal (const tripoint &p) const
 
point getabs (point p) const
 
tripoint getlocal (const tripoint &p) const
 Inverse of getabs. More...
 
tripoint getlocal (const tripoint_abs_ms &p) const
 
point getlocal (point p) const
 
virtual bool inbounds (const tripoint &p) const
 
bool inbounds (const tripoint_abs_ms &p) const
 
bool inbounds (point p) const
 
bool inbounds_z (const int z) const
 
void clip_to_bounds (tripoint &p) const
 Clips the coordinates of p to fit the map bounds. More...
 
void clip_to_bounds (int &x, int &y) const
 
void clip_to_bounds (int &x, int &y, int &z) const
 
int getmapsize () const
 
bool has_zlevels () const
 
void rotate (int turns, bool setpos_safe=false)
 Rotates this map, and all of its contents, by the specified multiple of 90 degrees. More...
 
void spawn_monsters (bool ignore_sight)
 Spawn monsters from submap spawn points and from the overmap. More...
 
void rotten_item_spawn (const item &item, const tripoint &p)
 Checks to see if the item that is rotting away generates a creature when it does. More...
 
void build_outside_cache (int zlev)
 
bool build_floor_cache (int zlev)
 
void build_floor_caches ()
 
void update_suspension_cache (const int &z)
 
bash_results bash_items (const tripoint &p, const bash_params &params)
 
bash_results bash_field (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_success (const tripoint &p, const bash_params &params)
 
bash_results bash_furn_success (const tripoint &p, const bash_params &params)
 
void process_items ()
 
const level_cacheget_cache_ref (int zlev) const
 
const pathfinding_cacheget_pathfinding_cache_ref (int zlev) const
 
void update_pathfinding_cache (int zlev) const
 
void update_visibility_cache (int zlev)
 
const visibility_variablesget_visibility_variables_cache () const
 
void update_submap_active_item_status (const tripoint &p)
 
const std::set< tripoint > & get_submaps_with_active_items () const
 
tripoint_range< tripointpoints_in_rectangle (const tripoint &from, const tripoint &to) const
 
tripoint_range< tripointpoints_in_radius (const tripoint &center, size_t radius, size_t radiusz=0) const
 
tripoint_range< tripointpoints_on_zlevel () const
 Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub). More...
 
tripoint_range< tripointpoints_on_zlevel (int z) const
 Same as above, but uses the specific z-level. More...
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius) const
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius, special_item_type type) const
 
std::list< tripointfind_furnitures_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures with matching flag in the specified radius More...
 
std::list< tripointfind_furnitures_or_vparts_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures or vehicle parts with matching flag in the specified radius More...
 
std::list< Creature * > get_creatures_in_radius (const tripoint &center, size_t radius, size_t radiusz=0)
 returns creatures in specified radius More...
 
level_cacheaccess_cache (int zlev)
 
const level_cacheaccess_cache (int zlev) const
 
bool dont_draw_lower_floor (const tripoint &p)
 
void support_dirty (const tripoint &p)
 
void spawn_monsters_submap (const tripoint &gp, bool ignore_sight)
 
void spawn_monsters_submap_group (const tripoint &gp, mongroup &group, bool ignore_sight)
 
fieldget_field (const tripoint &p)
 
submapgetsubmap (size_t grididx) const
 Get the submap pointer with given index in grid, the index must be valid! More...
 
submapget_submap_at (const tripoint &p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (point p) const
 
submapget_submap_at (const tripoint &p, point &offset_p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (point p, point &offset_p) const
 
submapget_submap_at_grid (point gridp) const
 Get submap pointer in the grid at given grid coordinates. More...
 
submapget_submap_at_grid (const tripoint &gridp) const
 
int calc_max_populated_zlev ()
 Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache. More...
 
void invalidate_max_populated_zlev (int zlev)
 Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value. More...
 
int move_cost_internal (const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
 Internal versions of public functions to avoid checking same variables multiple times. More...
 
int bash_rating_internal (int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
 
bool draw_maptile (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Internal version of the drawsq. More...
 
void draw_from_above (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Draws the tile as seen from above. More...
 
int determine_wall_corner (const tripoint &p) const
 
void apply_light_source (const tripoint &p, float luminance)
 
void add_light_source (const tripoint &p, float luminance)
 
void apply_directional_light (const tripoint &p, int direction, float luminance)
 
void apply_light_arc (const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
 
void apply_light_ray (bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
 
void add_light_from_items (const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
 
std::unique_ptr< vehicleadd_vehicle_to_map (std::unique_ptr< vehicle > veh, bool merge_wrecks)
 Takes a vehicle already created with new and attempts to place it on the map, checking for collisions. More...
 
ter_id get_roof (const tripoint &p, bool allow_air) const
 
void process_items_in_submap (submap &current_submap, const tripoint &gridp)
 
void process_items_in_vehicles (submap &current_submap)
 
void process_items_in_vehicle (vehicle &cur_veh, submap &current_submap)
 
template<typename Functor >
void function_over (const tripoint &start, const tripoint &end, Functor fun) const
 Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time. More...
 
level_cacheget_cache (int zlev) const
 
pathfinding_cacheget_pathfinding_cache (int zlev) const
 
void saven (const tripoint &grid)
 
void loadn (const tripoint &grid, bool update_vehicles)
 
void loadn (point grid, bool update_vehicles)
 
void actualize (const tripoint &grid)
 Fast forward a submap that has just been loading into this map. More...
 
void add_roofs (const tripoint &grid)
 Hacks in missing roofs. More...
 
template<typename Container >
void remove_rotten_items (Container &items, const tripoint &p, temperature_flag temperature)
 Go through the list of items, update their rotten status and remove items that have rotten away completely. More...
 
void fill_funnels (const tripoint &p, const time_point &since)
 Try to fill funnel based items here. More...
 
void grow_plant (const tripoint &p)
 Try to grow a harvestable plant to the next stage(s). More...
 
void restock_fruits (const tripoint &p, const time_duration &time_since_last_actualize)
 Try to grow fruits on static plants (not planted by the player) More...
 
void produce_sap (const tripoint &p, const time_duration &time_since_last_actualize)
 Produce sap on tapped maple trees. More...
 
void rad_scorch (const tripoint &p, const time_duration &time_since_last_actualize)
 Radiation-related plant (and fungus?) death. More...
 
void decay_cosmetic_fields (const tripoint &p, const time_duration &time_since_last_actualize)
 
void player_in_field (player &u)
 
void monster_in_field (monster &z)
 
void shift_traps (const tripoint &shift)
 As part of the map shifting, this shifts the trap locations stored in traplocs. More...
 
void copy_grid (const tripoint &to, const tripoint &from)
 
void draw_map (mapgendata &dat)
 
void draw_office_tower (mapgendata &dat)
 
void draw_lab (mapgendata &dat)
 
void draw_temple (mapgendata &dat)
 
void draw_mine (mapgendata &dat)
 
void draw_anthill (mapgendata &dat)
 
void draw_slimepit (mapgendata &dat)
 
void draw_triffid (mapgendata &dat)
 
void draw_connections (mapgendata &dat)
 
bool build_transparency_cache (int zlev)
 
bool build_vision_transparency_cache (const Character &player)
 
void build_sunlight_cache (int pzlev)
 
void generate_lightmap (int zlev)
 
void build_seen_cache (const tripoint &origin, int target_z)
 Calculates the Field Of View for the provided map from the given x, y coordinates. More...
 
void apply_character_light (Character &p)
 
void apply_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void restore_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void set_abs_sub (const tripoint &p)
 Sets abs_sub, see there. More...
 
size_t get_nonant (const tripoint &gridp) const
 Get the index of a submap pointer in the grid given by grid coordinates. More...
 
size_t get_nonant (point gridp) const
 
void setsubmap (size_t grididx, submap *smap)
 Set the submap pointer in grid at the give index. More...
 

Detailed Description

Manage and cache data about a part of the map.

Despite the name, this class isn't actually responsible for managing the map as a whole. For that function, see mapbuffer. Instead, this class loads a part of the mapbuffer into a cache, and adds certain temporary information such as lighting calculations to it.

To understand the following descriptions better, you should also read Map Management

The map coordinates always start at (0, 0) for the top-left and end at (map_width-1, map_height-1) for the bottom-right.

The actual map data is stored in submap instances. These instances are managed by mapbuffer. References to the currently active submaps are stored in map::grid: 0 1 2 3 4 5 6 7 8 In this example, the top-right submap would be at grid[2].

When the player moves between submaps, the whole map is shifted, so that if the player moves one submap to the right, (0, 0) now points to a tile one submap to the right from before

Definition at line 383 of file map.h.

Member Enumeration Documentation

◆ iteration_state

enum map::iteration_state
private

Enum used by functors in function_over to control execution.

Enumerator
ITER_CONTINUE 
ITER_SKIP_SUBMAP 
ITER_SKIP_ZLEVEL 
ITER_FINISH 

Definition at line 1928 of file map.h.

1928 {
1929 ITER_CONTINUE = 0, // Keep iterating
1930 ITER_SKIP_SUBMAP, // Skip the rest of this submap
1931 ITER_SKIP_ZLEVEL, // Skip the rest of this z-level
1932 ITER_FINISH // End iteration
1933 };
@ ITER_SKIP_ZLEVEL
Definition: map.h:1931
@ ITER_SKIP_SUBMAP
Definition: map.h:1930
@ ITER_CONTINUE
Definition: map.h:1929
@ ITER_FINISH
Definition: map.h:1932

Constructor & Destructor Documentation

◆ map() [1/2]

map::map ( int  mapsize = MAPSIZE,
bool  zlev = false 
)

Definition at line 175 of file map.cpp.

176{
177 my_MAPSIZE = mapsize;
178 zlevels = zlev;
179 if( zlevels ) {
180 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE * OVERMAP_LAYERS ), nullptr );
181 } else {
182 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE ), nullptr );
183 }
184
185 for( auto &ptr : caches ) {
186 ptr = std::make_unique<level_cache>();
187 }
188
189 for( auto &ptr : pathfinding_caches ) {
190 ptr = std::make_unique<pathfinding_cache>();
191 }
192
193 dbg( DL::Info ) << "map::map(): my_MAPSIZE: " << my_MAPSIZE << " z-levels enabled:" << zlevels;
194 traplocs.resize( trap::count() );
195}
std::vector< std::vector< tripoint > > traplocs
This vector contains an entry for each trap type, it has therefor the same size as the traplist vecto...
Definition: map.h:1960
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERS > pathfinding_caches
Definition: map.h:1970
std::vector< submap * > grid
The list of currently loaded submaps.
Definition: map.h:1953
int my_MAPSIZE
Definition: map.h:1781
bool zlevels
Definition: map.h:1782
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERS > caches
Holds caches for visibility, light, transparency and vehicles.
Definition: map.h:1968
@ Info
Information (default: enabled).
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
static constexpr int OVERMAP_LAYERS
#define dbg(x)
Definition: map.cpp:139
static size_t count()
Definition: trap.cpp:95

References caches, trap::count(), dbg, grid, Info, my_MAPSIZE, OVERMAP_LAYERS, pathfinding_caches, ptr(), traplocs, and zlevels.

Referenced by check_submap_active_item_consistency().

◆ map() [2/2]

map::map ( bool  zlev)
inlineexplicit

Definition at line 391 of file map.h.

391: map( MAPSIZE, zlev ) { }
map(int mapsize=MAPSIZE, bool zlev=false)
Definition: map.cpp:175
static constexpr int MAPSIZE

◆ ~map()

map::~map ( )
virtualdefault

Member Function Documentation

◆ access_cache() [1/2]

level_cache & map::access_cache ( int  zlev)

Definition at line 8860 of file map.cpp.

8861{
8862 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8863 return *caches[zlev + OVERMAP_DEPTH];
8864 }
8865
8866 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8867 return nullcache;
8868}
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:74
static constexpr int OVERMAP_HEIGHT
static constexpr int OVERMAP_DEPTH
static level_cache nullcache
Definition: map.cpp:143

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by get_known_connections(), explosion_handler::legacy_shrapnel(), game::place_player_overmap(), process_items(), scent_map::update(), and game::vertical_shift().

◆ access_cache() [2/2]

const level_cache & map::access_cache ( int  zlev) const

Definition at line 8870 of file map.cpp.

8871{
8872 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8873 return *caches[zlev + OVERMAP_DEPTH];
8874 }
8875
8876 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8877 return nullcache;
8878}

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ accessible_items()

bool map::accessible_items ( const tripoint t) const

Check whether the player can access the items located .

Certain furniture/terrain may prevent that (e.g. a locked safe).

Definition at line 6666 of file map.cpp.

6667{
6668 return !has_flag( "SEALED", t ) || has_flag( "LIQUIDCONT", t );
6669}
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2374

References has_flag().

Referenced by basecamp::form_crafting_inventory(), inventory::form_from_map(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), try_fuel_fire(), and use_charges().

◆ actualize()

void map::actualize ( const tripoint grid)
protected

Fast forward a submap that has just been loading into this map.

This is used to rot and remove rotten items, grow plants, fill funnels etc.

Definition at line 7517 of file map.cpp.

7518{
7519 submap *const tmpsub = get_submap_at_grid( grid );
7520 if( tmpsub == nullptr ) {
7521 debugmsg( "Actualize called on null submap (%d,%d,%d)", grid.x, grid.y, grid.z );
7522 return;
7523 }
7524
7525 const time_duration time_since_last_actualize = calendar::turn - tmpsub->last_touched;
7526 const bool do_funnels = ( grid.z >= 0 );
7527
7528 // check spoiled stuff, and fill up funnels while we're at it
7529 for( int x = 0; x < SEEX; x++ ) {
7530 for( int y = 0; y < SEEY; y++ ) {
7531 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7532 const point p( x, y );
7533 const auto &furn = this->furn( pnt ).obj();
7534 if( furn.has_flag( "EMITTER" ) ) {
7535 field_furn_locs.push_back( pnt );
7536 }
7537 // plants contain a seed item which must not be removed under any circumstances
7538 if( !furn.has_flag( "DONT_REMOVE_ROTTEN" ) ) {
7540 remove_rotten_items( tmpsub->get_items( { x, y } ), pnt, temperature );
7541 }
7542
7543 const auto trap_here = tmpsub->get_trap( p );
7544 if( trap_here != tr_null ) {
7545 traplocs[trap_here.to_i()].push_back( pnt );
7546 }
7547 const ter_t &ter = tmpsub->get_ter( p ).obj();
7548 if( ter.trap != tr_null && ter.trap != tr_ledge ) {
7549 traplocs[ter.trap.to_i()].push_back( pnt );
7550 }
7551
7552 if( do_funnels ) {
7553 fill_funnels( pnt, tmpsub->last_touched );
7554 }
7555
7556 grow_plant( pnt );
7557
7558 restock_fruits( pnt, time_since_last_actualize );
7559
7560 produce_sap( pnt, time_since_last_actualize );
7561
7562 rad_scorch( pnt, time_since_last_actualize );
7563
7564 decay_cosmetic_fields( pnt, time_since_last_actualize );
7565 }
7566 }
7567
7568 // the last time we touched the submap, is right now.
7569 tmpsub->last_touched = calendar::turn;
7570}
const T & obj() const
Definition: ammo_effect.cpp:26
int to_i() const
Returns the identifier as plain int.
Definition: int_id.h:84
void rad_scorch(const tripoint &p, const time_duration &time_since_last_actualize)
Radiation-related plant (and fungus?) death.
Definition: map.cpp:7451
void fill_funnels(const tripoint &p, const time_point &since)
Try to fill funnel based items here.
Definition: map.cpp:7239
submap * get_submap_at_grid(point gridp) const
Get submap pointer in the grid at given grid coordinates.
Definition: map.h:1831
void remove_rotten_items(Container &items, const tripoint &p, temperature_flag temperature)
Go through the list of items, update their rotten status and remove items that have rotten away compl...
Definition: map.cpp:7200
std::vector< tripoint > field_furn_locs
Vector of tripoints containing active field-emitting furniture.
Definition: map.h:1964
void decay_cosmetic_fields(const tripoint &p, const time_duration &time_since_last_actualize)
Definition: map.cpp:7497
void restock_fruits(const tripoint &p, const time_duration &time_since_last_actualize)
Try to grow fruits on static plants (not planted by the player)
Definition: map.cpp:7340
ter_id ter(const tripoint &p) const
Definition: map.cpp:1562
void grow_plant(const tripoint &p)
Try to grow a harvestable plant to the next stage(s).
Definition: map.cpp:7262
void produce_sap(const tripoint &p, const time_duration &time_since_last_actualize)
Produce sap on tapped maple trees.
Definition: map.cpp:7354
furn_id furn(const tripoint &p) const
Definition: map.cpp:1412
Definition: submap.h:65
time_point last_touched
Definition: submap.h:211
trap_id get_trap(point p) const
Definition: submap.h:73
ter_id get_ter(point p) const
Definition: submap.h:99
cata::colony< item > & get_items(point p)
Definition: submap.h:140
A duration defined as a number of specific time units.
Definition: calendar.h:180
point sm_to_ms_copy(point p)
temperature_flag
Definition: enums.h:42
static constexpr int SEEX
static constexpr int SEEY
static temperature_flag temperature_flag_at_point(const map &m, const tripoint &p)
Definition: map.cpp:4705
static const trap_str_id tr_ledge("tr_ledge")
time_point turn
Definition: calendar.cpp:36
quantity< int, temperature_in_millidegree_celsius_tag > temperature
Definition: point.h:35
Definition: mapdata.h:461
trap_id tr_null
Definition: trap.cpp:276

References debugmsg, decay_cosmetic_fields(), field_furn_locs, fill_funnels(), furn(), submap::get_items(), get_submap_at_grid(), submap::get_ter(), submap::get_trap(), grid, grow_plant(), submap::last_touched, int_id< T >::obj(), produce_sap(), rad_scorch(), remove_rotten_items(), restock_fruits(), SEEX, SEEY, sm_to_ms_copy(), temperature_flag_at_point(), ter(), int_id< T >::to_i(), tr_ledge, tr_null, traplocs, and calendar::turn.

Referenced by loadn().

◆ add_camp()

void map::add_camp ( const tripoint_abs_omt omt_pos,
const std::string &  name 
)

Definition at line 5689 of file map.cpp.

5690{
5691 basecamp temp_camp = basecamp( name, omt_pos );
5692 overmap_buffer.add_camp( temp_camp );
5693 g->u.camps.insert( omt_pos );
5694 g->validate_camps();
5695}
std::string name(const tripoint &p)
Definition: map.cpp:1389
void add_camp(const basecamp &camp)
Add Basecamp to overmapbuffer.
std::unique_ptr< game > g
Definition: game.cpp:281
overmapbuffer overmap_buffer

References overmapbuffer::add_camp(), g, name(), and overmap_buffer.

Referenced by get_basecamp().

◆ add_computer()

computer * map::add_computer ( const tripoint p,
const std::string &  name,
int  security 
)

Definition at line 5816 of file mapgen.cpp.

5817{
5818 // TODO: Turn this off?
5819 ter_set( p, t_console );
5820 point l;
5821 submap *const place_on_submap = get_submap_at( p, l );
5822 place_on_submap->set_computer( l, computer( name, security ) );
5823 return place_on_submap->get_computer( l );
5824}
bool ter_set(const tripoint &p, const ter_id &new_terrain)
Definition: map.cpp:1703
submap * get_submap_at(const tripoint &p) const
Get the submap pointer containing the specified position within the reality bubble.
Definition: map.cpp:8429
void set_computer(point p, const computer &c)
Definition: submap.cpp:238
const computer * get_computer(point p) const
Definition: submap.cpp:212
ter_id t_console
Definition: mapdata.cpp:706

References submap::get_computer(), get_submap_at(), name(), submap::set_computer(), t_console, and ter_set().

Referenced by jmapgen_computer::apply(), create_lab_consoles(), draw_lab(), mission_start::place_npc_software(), and science_room().

◆ add_corpse()

void map::add_corpse ( const tripoint p)

Definition at line 8573 of file map.cpp.

8574{
8575 item body;
8576
8577 const bool isReviveSpecial = one_in( 10 );
8578
8579 if( !isReviveSpecial ) {
8580 body = item::make_corpse();
8581 } else {
8582 body = item::make_corpse( mon_zombie );
8583 body.set_flag( "REVIVE_SPECIAL" );
8584 }
8585
8586 put_items_from_loc( item_group_id( "default_zombie_clothes" ), p );
8587 if( one_in( 3 ) ) {
8588 put_items_from_loc( item_group_id( "default_zombie_items" ), p );
8589 }
8590
8591 add_item_or_charges( p, body );
8592}
Definition: item.h:211
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:507
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5332
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4332
std::vector< item * > put_items_from_loc(const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
Place items from an item group at p.
Definition: mapgen.cpp:5604
static const mtype_id mon_zombie("mon_zombie")
bool one_in(int chance)
Definition: rng.cpp:65
string_id< Item_group > item_group_id
Definition: type_id.h:77

References add_item_or_charges(), item::make_corpse(), mon_zombie, one_in(), put_items_from_loc(), and item::set_flag().

Referenced by add_corpse(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), and MapExtras::mx_minefield().

◆ add_field()

bool map::add_field ( const tripoint p,
const field_type_id type_id,
int  intensity = INT_MAX,
const time_duration age = 0_turns,
bool  hit_player = true 
)

Add field entry at point, or set intensity if present.

Returns
false if the field could not be created (out of bounds), otherwise true.

Definition at line 5506 of file map.cpp.

5508{
5509 if( !inbounds( p ) ) {
5510 return false;
5511 }
5512
5513 if( !type_id ) {
5514 debugmsg( "Tried to add null field" );
5515 return false;
5516 }
5517
5518 const field_type &fd_type = *type_id;
5519 intensity = std::min( intensity, fd_type.get_max_intensity() );
5520 if( intensity <= 0 ) {
5521 return false;
5522 }
5523
5524 point l;
5525 submap *const current_submap = get_submap_at( p, l );
5526 current_submap->is_uniform = false;
5528
5529 if( current_submap->get_field( l ).add_field( type_id, intensity, age ) ) {
5530 //Only adding it to the count if it doesn't exist.
5531 if( !current_submap->field_count++ ) {
5532 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5533 p.y / SEEX ) * MAPSIZE ) ) );
5534 }
5535 }
5536
5537 if( hit_player ) {
5538 Character &player_character = get_player_character();
5539 if( g != nullptr && this == &get_map() && p == player_character.pos() ) {
5540 //Hit the player with the field if it spawned on top of them.
5541 creature_in_field( player_character );
5542 }
5543 }
5544
5545 // Dirty the transparency cache now that field processing doesn't always do it
5546 if( fd_type.dirty_transparency_cache || !fd_type.is_transparent() ) {
5549 }
5550
5551 if( fd_type.is_dangerous() ) {
5553 }
5554
5555 // Ensure blood type fields don't hang in the air
5556 if( zlevels && fd_type.accelerated_decay ) {
5557 support_dirty( p );
5558 }
5559
5560 return true;
5561}
Character & get_player_character()
Definition: character.cpp:394
const tripoint & pos() const override
Definition: character.cpp:592
bool add_field(const field_type_id &field_type_to_add, int new_intensity=1, const time_duration &new_age=0_turns)
Inserts the given field_type_id into the field list for a given tile if it does not already exist.
Definition: field.cpp:190
void set_transparency_cache_dirty(const int zlev)
Sets a dirty flag on the a given cache.
Definition: map.cpp:200
level_cache & get_cache(int zlev) const
Definition: map.h:1988
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7873
void set_pathfinding_cache_dirty(int zlev)
Definition: map.cpp:8915
void creature_in_field(Creature &critter)
Apply field effects to the creature when it's on a square with fields.
Definition: map_field.cpp:1562
void support_dirty(const tripoint &p)
Definition: map.cpp:2348
void invalidate_max_populated_zlev(int zlev)
Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above curre...
Definition: map.cpp:9146
void set_seen_cache_dirty(const tripoint change_location)
Definition: map.cpp:207
field & get_field(point p)
Definition: submap.h:149
int field_count
Definition: submap.h:210
bool is_uniform
Definition: submap.h:204
map & get_map()
Definition: map.cpp:147
bool accelerated_decay
Definition: field_type.h:179
bool is_transparent() const
Definition: field_type.h:262
bool dirty_transparency_cache
Definition: field_type.h:161
bool is_dangerous() const
Definition: field_type.h:256
int get_max_intensity() const
Definition: field_type.h:268
std::bitset< MAPSIZE *MAPSIZE > field_cache
Definition: map.h:352
int y
Definition: point.h:137
int z
Definition: point.h:138
int x
Definition: point.h:136

References field_type::accelerated_decay, field::add_field(), creature_in_field(), debugmsg, field_type::dirty_transparency_cache, level_cache::field_cache, submap::field_count, g, get_cache(), submap::get_field(), get_map(), field_type::get_max_intensity(), get_player_character(), get_submap_at(), inbounds(), invalidate_max_populated_zlev(), field_type::is_dangerous(), field_type::is_transparent(), submap::is_uniform, MAPSIZE, Character::pos(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by Character::activate_bionic(), explosion_handler::ExplosionProcess::add_field(), jmapgen_field::apply(), apply_ammo_effects(), Character::blossoms(), mattack::boomer(), mattack::boomer_glow(), start_location::burn(), create_anomaly(), spell::create_field(), create_hot_air(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), drop_fields(), editmap::edit_fld(), iexamine::fireplace(), mattack::flame(), gas_spread_to(), hit_with_fire(), explosion_handler::legacy_blast(), madd_field(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_spider(), game::process_artifact(), process_fields_in_submap(), item::process_litcig(), explosion_handler::explosion_funcs::resonance_cascade(), mattack::riotbot(), set_field_intensity(), shoot(), Character::suffer_from_other_mutations(), explosion_iuse::trigger_explosion(), and consume_drug_iuse::use().

◆ add_item() [1/2]

item & map::add_item ( const tripoint p,
item  new_item 
)

Place an item on the map, despite the parameter name, this is not necessarily a new item.

WARNING: does -not- check volume or stack charges. player functions (drop etc) should use map::add_item_or_charges

Returns
The item that got added, or nulitem.

Definition at line 4432 of file map.cpp.

4433{
4434 if( !inbounds( p ) ) {
4435 return null_item_reference();
4436 }
4437 point l;
4438 submap *const current_submap = get_submap_at( p, l );
4439
4440 // Process foods when they are added to the map, here instead of add_item_at()
4441 // to avoid double processing food and corpses during active item processing.
4442 if( new_item.is_food() ) {
4443 new_item.process( nullptr, p, false );
4444 }
4445
4446 if( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) {
4447 return null_item_reference();
4448 }
4449
4450 if( has_flag( "DESTROY_ITEM", p ) ) {
4451 return null_item_reference();
4452 }
4453
4454 if( new_item.has_flag( "ACT_IN_FIRE" ) && get_field( p, fd_fire ) != nullptr ) {
4455 if( new_item.has_flag( "BOMB" ) && new_item.is_transformable() ) {
4456 //Convert a bomb item into its transformable version, e.g. incendiary grenade -> active incendiary grenade
4457 new_item.convert( dynamic_cast<const iuse_transform *>
4458 ( new_item.type->get_use( "transform" )->get_actor_ptr() )->target );
4459 }
4460 new_item.active = true;
4461 }
4462
4463 if( new_item.is_map() && !new_item.has_var( "reveal_map_center_omt" ) ) {
4464 new_item.set_var( "reveal_map_center_omt", ms_to_omt_copy( getabs( p ) ) );
4465 }
4466
4467 current_submap->is_uniform = false;
4469
4470 current_submap->update_lum_add( l, new_item );
4471
4472 const map_stack::iterator new_pos = current_submap->get_items( l ).insert( new_item );
4473 if( new_item.needs_processing() ) {
4474 if( current_submap->active_items.empty() ) {
4475 submaps_with_active_items.insert( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4476 }
4477 current_submap->active_items.add( *new_pos, l );
4478 }
4479
4480 return *new_pos;
4481}
void add(item &it, point location)
Adds the reference to the cache.
bool empty() const
Returns true if the cache is empty.
bool is_transformable() const
Definition: item.cpp:6958
bool process(player *carrier, const tripoint &pos, bool activate, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9586
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8930
bool active
Definition: item.h:2234
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6413
item & convert(const itype_id &new_type)
Filter converting this instance to another type preserving all other aspects.
Definition: item.cpp:533
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1075
void set_var(const std::string &name, int value)
Definition: item.cpp:1000
bool has_flag(const std::string &flag) const
Definition: item.cpp:5303
bool is_map() const
Definition: item.cpp:6714
bool is_food() const
Definition: item.cpp:6592
const itype * type
Definition: item.h:2157
Transform an item into a specific type.
Definition: iuse_actor.h:52
itype_id target
type of the resulting item
Definition: iuse_actor.h:58
std::set< tripoint > submaps_with_active_items
Set of submaps that contain active items in absolute coordinates.
Definition: map.h:1974
field_entry * get_field(const tripoint &p, const field_type_id &type)
Get field of specific type at point.
Definition: map.cpp:5483
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8377
tripoint abs_sub
Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapb...
Definition: map.h:1796
void update_lum_add(point p, const item &i)
Definition: submap.h:130
active_item_cache active_items
Definition: submap.h:208
point ms_to_omt_copy(point p)
@ LIQUID
Definition: enums.h:175
field_type_id fd_fire
Definition: field_type.cpp:345
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:322
const use_function * get_use(const std::string &iuse_name) const
Definition: itype.cpp:166
iuse_actor * get_actor_ptr()
Definition: iuse.h:315

References abs_sub, item::active, submap::active_items, active_item_cache::add(), item::convert(), active_item_cache::empty(), fd_fire, use_function::get_actor_ptr(), get_field(), submap::get_items(), get_submap_at(), itype::get_use(), getabs(), item::has_flag(), has_flag(), item::has_var(), inbounds(), invalidate_max_populated_zlev(), item::is_food(), item::is_map(), item::is_transformable(), submap::is_uniform, LIQUID, item::made_of(), ms_to_omt_copy(), item::needs_processing(), null_item_reference(), item::process(), SEEX, SEEY, item::set_var(), submaps_with_active_items, iuse_transform::target, item::type, submap::update_lum_add(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_item(), add_item_or_charges(), item::ammo_consume(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), explosion_handler::ExplosionProcess::blast_tile(), draw_mine(), extract_or_wreck_cbms(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), mill_activate(), mill_load_food(), explosion_handler::ExplosionProcess::move_entity(), Character::perform_uninstall(), place_gas_pump(), place_toilet(), iexamine::pour_into_keg(), iexamine::reload_furniture(), smoker_activate(), smoker_load_food(), Character::uninstall_bionic(), and avatar_action::wield().

◆ add_item() [2/2]

void map::add_item ( point  p,
item  new_item 
)
inline

Definition at line 1248 of file map.h.

1248 {
1249 add_item( tripoint( p, abs_sub.z ), new_item );
1250 }
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4432

References abs_sub, add_item(), and tripoint::z.

◆ add_item_or_charges() [1/2]

item & map::add_item_or_charges ( const tripoint pos,
item  obj,
bool  overflow = true 
)

Adds an item to map tile or stacks charges.

Parameters
posWhere to add item
objItem to add
overflowif destination is full attempt to drop on adjacent tiles
Returns
reference to dropped (and possibly stacked) item or null item on failure
Warning
function is relatively expensive and meant for user initiated actions, not mapgen

Definition at line 4332 of file map.cpp.

4333{
4334 // Checks if item would not be destroyed if added to this tile
4335 auto valid_tile = [&]( const tripoint & e ) {
4336 if( !inbounds( e ) ) {
4337 // should never happen
4338 debugmsg( "add_item_or_charges: %s is out of bounds (adding item '%s' [%d])",
4339 e.to_string(), obj.typeId().c_str(), obj.charges );
4340 return false;
4341 }
4342
4343 // Some tiles destroy items (e.g. lava)
4344 if( has_flag( "DESTROY_ITEM", e ) ) {
4345 return false;
4346 }
4347
4348 // Cannot drop liquids into tiles that are comprised of liquid
4349 if( obj.made_of( LIQUID ) && has_flag( "SWIMMABLE", e ) ) {
4350 return false;
4351 }
4352
4353 return true;
4354 };
4355
4356 // Checks if sufficient space at tile to add item
4357 auto valid_limits = [&]( const tripoint & e ) {
4358 return obj.volume() <= free_volume( e ) && i_at( e ).size() < MAX_ITEM_IN_SQUARE;
4359 };
4360
4361 // Performs the actual insertion of the object onto the map
4362 auto place_item = [&]( const tripoint & tile ) -> item& {
4363 if( obj.count_by_charges() )
4364 {
4365 for( auto &e : i_at( tile ) ) {
4366 if( e.merge_charges( obj ) ) {
4367 return e;
4368 }
4369 }
4370 }
4371
4372 support_dirty( tile );
4373 return add_item( tile, obj );
4374 };
4375
4376 // Some items never exist on map as a discrete item (must be contained by another item)
4377 if( obj.has_flag( "NO_DROP" ) ) {
4378 return null_item_reference();
4379 }
4380
4381 // If intended drop tile destroys the item then we don't attempt to overflow
4382 if( !valid_tile( pos ) ) {
4383 return null_item_reference();
4384 }
4385
4386 if( ( !has_flag( "NOITEM", pos ) || ( has_flag( "LIQUIDCONT", pos ) && obj.made_of( LIQUID ) ) )
4387 && valid_limits( pos ) ) {
4388 // Pass map into on_drop, because this map may not be the global map object (in mapgen, for instance).
4389 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4390 if( obj.on_drop( pos, *this ) ) {
4391 return null_item_reference();
4392 }
4393
4394 }
4395 // If tile can contain items place here...
4396 return place_item( pos );
4397
4398 } else if( overflow ) {
4399 // ...otherwise try to overflow to adjacent tiles (if permitted)
4400 const int max_dist = 2;
4401 std::vector<tripoint> tiles = closest_points_first( pos, max_dist );
4402 tiles.erase( tiles.begin() ); // we already tried this position
4403 const int max_path_length = 4 * max_dist;
4404 const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false,
4405 false );
4406 for( const tripoint &e : tiles ) {
4407 if( !inbounds( e ) ) {
4408 continue;
4409 }
4410 //must be a path to the target tile
4411 if( route( pos, e, setting ).empty() ) {
4412 continue;
4413 }
4414 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4415 if( obj.on_drop( e, *this ) ) {
4416 return null_item_reference();
4417 }
4418 }
4419
4420 if( !valid_tile( e ) || !valid_limits( e ) ||
4421 has_flag( "NOITEM", e ) || has_flag( "SEALED", e ) ) {
4422 continue;
4423 }
4424 return place_item( e );
4425 }
4426 }
4427
4428 // failed due to lack of space at target tile (+/- overflow tiles)
4429 return null_item_reference();
4430}
size_t size() const
Definition: item_stack.cpp:10
bool count_by_charges() const
Definition: item.cpp:6005
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5104
int charges
Definition: item.h:2196
bool on_drop(const tripoint &pos)
Invokes item type's itype::drop_action.
Definition: item.cpp:9982
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8353
map_stack i_at(const tripoint &p)
Definition: map.cpp:4187
units::volume free_volume(const tripoint &p)
Definition: map.cpp:4327
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:247
std::vector< coords::coord_point< Point, Origin, Scale > > closest_points_first(const coords::coord_point< Point, Origin, Scale > &loc, int min_dist, int max_dist)
Definition: coordinates.h:596
static constexpr int MAX_ITEM_IN_SQUARE

References add_item(), string_id< T >::c_str(), item::charges, closest_points_first(), item::count_by_charges(), debugmsg, free_volume(), item::has_flag(), has_flag(), i_at(), inbounds(), LIQUID, item::made_of(), MAX_ITEM_IN_SQUARE, null_item_reference(), item::on_drop(), wrapped_vehicle::pos, route(), item_stack::size(), support_dirty(), item::typeId(), and item::volume().

Referenced by Character::absorb_hit(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_sample(), Character::activate_bionic(), add_corpse(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), jmapgen_liquid_item::apply(), butchery_drops_harvest(), butchery_quarter(), defense_game::caravan(), game::catch_a_monster(), activity_handlers::chop_logs_finish(), doors::close_door(), talk_function::companion_return(), complete_construction(), cycle_action(), vehicle::damage_direct(), monexamine::deactivate_pet(), iexamine::deployed_furniture(), game::disable_robot(), basecamp::distribute_food(), draw_lab(), Character::drop_invalid_inventory(), drop_items(), npc::drop_items(), drop_on_map(), drop_or_embed_projectile(), talk_function::drop_stolen_item(), talk_function::drop_weapon(), monexamine::dump_items(), iexamine::elevator(), explosion_handler::emp_blast(), farm_action(), fetch_activity(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), iexamine::fireplace(), game::forced_door_closing(), fromPumpFuel(), iexamine::fvat_full(), iexamine::gaspump(), handle_harvest(), pickup::handle_spillable_contents(), iexamine::harvest_plant(), Character::i_add_or_drop(), map_stack::insert(), make_mon_corpse(), mill_activate(), move_item(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), iexamine::nanofab(), om_set_hide_site(), liquid_handler::perform_liquid_transfer(), iexamine::pit_covered(), Character::place_corpse(), basecamp::place_results(), activity_handlers::plant_seed_finish(), talk_function::player_weapon_drop(), iexamine::portable_structure(), process_fields_in_submap(), item::process_litcig(), put_into_vehicle(), iexamine::quern_examine(), rcdrive(), monexamine::remove_armor(), monexamine::remove_bag_from(), monexamine::remove_battery(), rod_fish(), explosion_handler::ExplosionProcess::run(), scatter_chunks(), set_item_map(), activity_handlers::shear_finish(), smash_items(), smoker_activate(), iexamine::smoker_options(), spawn_an_item(), spawn_artifact(), spawn_items(), spawn_natural_artifact(), item::spill_contents(), item_contents::spill_contents(), mdeath::splatter(), stash_on_pet(), iexamine::toPumpFuel(), iexamine::trap(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), unroll_digging(), and unpack_actor::use().

◆ add_item_or_charges() [2/2]

item & map::add_item_or_charges ( point  p,
item  obj,
bool  overflow = true 
)
inline

Definition at line 1236 of file map.h.

1236 {
1237 return add_item_or_charges( tripoint( p, abs_sub.z ), obj, overflow );
1238 }

References abs_sub, add_item_or_charges(), and tripoint::z.

◆ add_light_from_items()

void map::add_light_from_items ( const tripoint p,
item_stack::iterator  begin,
item_stack::iterator  end 
)
private

Definition at line 86 of file lightmap.cpp.

88{
89 for( auto itm_it = begin; itm_it != end; ++itm_it ) {
90 float ilum = 0.0f; // brightness
91 units::angle iwidth = 0_degrees; // 0-360 degrees. 0 is a circular light_source
92 units::angle idir = 0_degrees; // otherwise, it's a light_arc pointed in this direction
93 if( itm_it->getlight( ilum, iwidth, idir ) ) {
94 if( iwidth > 0_degrees ) {
95 apply_light_arc( p, idir, ilum, iwidth );
96 } else {
97 add_light_source( p, ilum );
98 }
99 }
100 }
101}
void apply_light_arc(const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
Definition: lightmap.cpp:1870
void add_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:648

References add_light_source(), and apply_light_arc().

Referenced by generate_lightmap().

◆ add_light_source()

void map::add_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 648 of file lightmap.cpp.

649{
650 auto &light_source_buffer = get_cache( p.z ).light_source_buffer;
651 light_source_buffer[p.x][p.y] = std::max( luminance, light_source_buffer[p.x][p.y] );
652}
float light_source_buffer[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:318

References get_cache(), level_cache::light_source_buffer, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_light_from_items(), and generate_lightmap().

◆ add_roofs()

void map::add_roofs ( const tripoint grid)
protected

Hacks in missing roofs.

Should be removed when 3D mapgen is done.

Definition at line 7572 of file map.cpp.

7573{
7574 if( !zlevels ) {
7575 // No roofs required!
7576 // Why not? Because submaps below and above don't exist yet
7577 return;
7578 }
7579
7580 submap *const sub_here = get_submap_at_grid( grid );
7581 if( sub_here == nullptr ) {
7582 debugmsg( "Tried to add roofs/floors on null submap on %d,%d,%d",
7583 grid.x, grid.y, grid.z );
7584 return;
7585 }
7586
7587 bool check_roof = grid.z > -OVERMAP_DEPTH;
7588
7589 submap *const sub_below = check_roof ? get_submap_at_grid( grid + tripoint_below ) : nullptr;
7590
7591 if( check_roof && sub_below == nullptr ) {
7592 debugmsg( "Tried to add roofs to sm at %d,%d,%d, but sm below doesn't exist",
7593 grid.x, grid.y, grid.z );
7594 return;
7595 }
7596
7597 for( int x = 0; x < SEEX; x++ ) {
7598 for( int y = 0; y < SEEY; y++ ) {
7599 const ter_id ter_here = sub_here->get_ter( { x, y } );
7600 if( ter_here != t_open_air ) {
7601 continue;
7602 }
7603
7604 if( !check_roof ) {
7605 // Make sure we don't have open air at lowest z-level
7606 sub_here->set_ter( { x, y }, t_rock_floor );
7607 continue;
7608 }
7609
7610 const ter_t &ter_below = sub_below->get_ter( { x, y } ).obj();
7611 if( ter_below.roof ) {
7612 // TODO: Make roof variable a ter_id to speed this up
7613 sub_here->set_ter( { x, y }, ter_below.roof.id() );
7614 }
7615 }
7616 }
7617}
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54
void set_ter(point p, ter_id terr)
Definition: submap.h:103
ter_id t_open_air
Definition: mapdata.cpp:729
ter_id t_rock_floor
Definition: mapdata.cpp:629
static constexpr tripoint tripoint_below
Definition: point.h:281
ter_str_id roof
Definition: mapdata.h:471

References debugmsg, get_submap_at_grid(), submap::get_ter(), grid, string_id< T >::id(), OVERMAP_DEPTH, ter_t::roof, SEEX, SEEY, submap::set_ter(), t_open_air, t_rock_floor, tripoint_below, and zlevels.

Referenced by loadn(), and shift().

◆ add_spawn()

void map::add_spawn ( const mtype_id type,
int  count,
const tripoint p,
bool  friendly = false,
int  faction_id = -1,
int  mission_id = -1,
const std::string &  name = "NONE" 
) const

Definition at line 5611 of file mapgen.cpp.

5613{
5614 if( p.x < 0 || p.x >= SEEX * my_MAPSIZE || p.y < 0 || p.y >= SEEY * my_MAPSIZE ) {
5615 debugmsg( "Bad add_spawn(%s, %d, %d, %d)", type.c_str(), count, p.x, p.y );
5616 return;
5617 }
5618 point offset;
5619 submap *place_on_submap = get_submap_at( p, offset );
5620
5621 if( !place_on_submap ) {
5622 debugmsg( "centadodecamonant doesn't exist in grid; within add_spawn(%s, %d, %d, %d, %d)",
5623 type.c_str(), count, p.x, p.y, p.z );
5624 return;
5625 }
5627 return;
5628 }
5629 spawn_point tmp( type, count, offset, faction_id, mission_id, friendly, name );
5630 place_on_submap->spawns.push_back( tmp );
5631}
static bool monster_is_blacklisted(const mtype_id &m)
Definition: mongroup.cpp:280
std::vector< spawn_point > spawns
Definition: submap.h:212
constexpr size_t count()
Definition: fmtlib_core.h:1073

References detail::count(), debugmsg, friendly, get_submap_at(), MonsterGroupManager::monster_is_blacklisted(), my_MAPSIZE, name(), SEEX, SEEY, submap::spawns, type, tripoint::x, tripoint::y, and tripoint::z.

Referenced by jmapgen_monster::apply(), generate(), mission_start::kill_horde_master(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_hive(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_jabberwock(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_military(), MapExtras::mx_roadblock(), MapExtras::mx_science(), MapExtras::mx_shia(), MapExtras::mx_spider(), mission_start::place_dog(), place_spawns(), mission_start::place_zombie_mom(), process_fields_in_submap(), and rotten_item_spawn().

◆ add_splash()

void map::add_splash ( const field_type_id type,
const tripoint center,
int  radius,
int  intensity 
)

Definition at line 5638 of file map.cpp.

5640{
5641 if( !type.id() ) {
5642 return;
5643 }
5644 // TODO: use Bresenham here and take obstacles into account
5645 for( const tripoint &pnt : points_in_radius( center, radius ) ) {
5646 if( trig_dist( pnt, center ) <= radius && !one_in( intensity ) ) {
5647 add_splatter( type, pnt );
5648 }
5649 }
5650}
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8732
void add_splatter(const field_type_id &type, const tripoint &where, int intensity=1)
Definition: map.cpp:5589
int trig_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:512

References add_splatter(), center, one_in(), points_in_radius(), trig_dist(), and type.

Referenced by smash_items().

◆ add_splatter()

void map::add_splatter ( const field_type_id type,
const tripoint where,
int  intensity = 1 
)

Definition at line 5589 of file map.cpp.

5590{
5591 if( !type.id() || intensity <= 0 ) {
5592 return;
5593 }
5594 if( type.obj().is_splattering ) {
5595 if( const optional_vpart_position vp = veh_at( where ) ) {
5596 vehicle *const veh = &vp->vehicle();
5597 // Might be -1 if all the vehicle's parts at where are marked for removal
5598 const int part = veh->part_displayed_at( vp->mount() );
5599 if( part != -1 ) {
5600 veh->part( part ).blood += 200 * std::min( intensity, 3 ) / 3;
5601 return;
5602 }
5603 }
5604 }
5605 mod_field_intensity( where, type, intensity );
5606}
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1073
int mod_field_intensity(const tripoint &p, const field_type_id &type, int offset)
Increment/decrement intensity of field entry at point, creating if not present, removing if intensity...
Definition: map.cpp:5432
Simple wrapper to forward functions that may return a std::optional to vpart_position.
A vehicle as a whole with all its components.
Definition: vehicle.h:676
int part_displayed_at(point dp) const
Returns which part (as an index into the parts list) is the one that will be displayed for the given ...
Definition: vehicle.cpp:2971
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:252
vehicle_part & part(int part_num)
Definition: vehicle.cpp:7084
int blood
how much blood covers part (in turns).
Definition: vehicle.h:399

References vehicle_part::blood, mod_field_intensity(), vehicle::part(), vehicle::part_displayed_at(), type, veh_at(), and vehicle::vehicle().

Referenced by add_splash(), add_splatter_trail(), Creature::bleed(), activity_handlers::butcher_finish(), scatter_chunks(), and mdeath::splatter().

◆ add_splatter_trail()

void map::add_splatter_trail ( const field_type_id type,
const tripoint from,
const tripoint to 
)

Definition at line 5608 of file map.cpp.

5610{
5611 if( !type.id() ) {
5612 return;
5613 }
5614 auto trail = line_to( from, to );
5615 int remainder = trail.size();
5616 tripoint last_point = from;
5617 for( tripoint &elem : trail ) {
5618 add_splatter( type, elem );
5619 remainder--;
5620 if( obstructed_by_vehicle_rotation( last_point, elem ) ) {
5621 if( one_in( 2 ) ) {
5622 elem.x = last_point.x;
5623 add_splatter( type, elem, remainder );
5624 } else {
5625 elem.y = last_point.y;
5626 add_splatter( type, elem, remainder );
5627 }
5628 return;
5629 }
5630 if( impassable( elem ) ) { // Blood splatters stop at walls.
5631 add_splatter( type, elem, remainder );
5632 return;
5633 }
5634 last_point = elem;
5635 }
5636}
bool obstructed_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.
Definition: map.cpp:6593
bool impassable(const tripoint &p) const
Definition: map.cpp:1859
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548

References add_splatter(), impassable(), line_to(), obstructed_by_vehicle_rotation(), one_in(), type, tripoint::x, and tripoint::y.

Referenced by activity_handlers::butcher_finish(), MapExtras::mx_casings(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), projectile_attack(), and activity_handlers::pulp_do_turn().

◆ add_vehicle() [1/4]

vehicle * map::add_vehicle ( const vgroup_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

◆ add_vehicle() [2/4]

vehicle * map::add_vehicle ( const vgroup_id type,
point  p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5639 of file mapgen.cpp.

5641{
5642 return add_vehicle( type.obj().pick(), p, dir, veh_fuel, veh_status, merge_wrecks );
5643}

References add_vehicle(), and type.

◆ add_vehicle() [3/4]

vehicle * map::add_vehicle ( const vproto_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5651 of file mapgen.cpp.

5653{
5654 if( !type.is_valid() ) {
5655 debugmsg( "Nonexistent vehicle type: \"%s\"", type.c_str() );
5656 return nullptr;
5657 }
5658 if( !inbounds( p ) ) {
5659 dbg( DL::Warn ) << string_format( "Out of bounds add_vehicle t=%s d=%d p=%s",
5660 type, to_degrees( dir ), p.to_string() );
5661 return nullptr;
5662 }
5663
5664 // debugmsg("n=%d x=%d y=%d MAPSIZE=%d ^2=%d", nonant, x, y, MAPSIZE, MAPSIZE*MAPSIZE);
5665 auto veh = std::make_unique<vehicle>( type, veh_fuel, veh_status );
5666 tripoint p_ms = p;
5667 veh->sm_pos = ms_to_sm_remain( p_ms );
5668 veh->pos = p_ms.xy();
5669 veh->place_spawn_items();
5670 // for backwards compatibility, we always spawn with a pivot point of (0,0) so
5671 // that the mount at (0,0) is located at the spawn position.
5672 veh->set_facing_and_pivot( dir, point_zero, false );
5673 //debugmsg("adding veh: %d, sm: %d,%d,%d, pos: %d, %d", veh, veh->smx, veh->smy, veh->smz, veh->posx, veh->posy);
5674 std::unique_ptr<vehicle> placed_vehicle_up =
5675 add_vehicle_to_map( std::move( veh ), merge_wrecks );
5676 vehicle *placed_vehicle = placed_vehicle_up.get();
5677
5678 if( placed_vehicle != nullptr ) {
5679 submap *place_on_submap = get_submap_at_grid( placed_vehicle->sm_pos );
5680 place_on_submap->vehicles.push_back( std::move( placed_vehicle_up ) );
5681 place_on_submap->is_uniform = false;
5683
5684 auto &ch = get_cache( placed_vehicle->sm_pos.z );
5685 ch.vehicle_list.insert( placed_vehicle );
5686 add_vehicle_to_cache( placed_vehicle );
5687
5688 //debugmsg ("grid[%d]->vehicles.size=%d veh.parts.size=%d", nonant, grid[nonant]->vehicles.size(),veh.parts.size());
5689 }
5690 return placed_vehicle;
5691}
std::unique_ptr< vehicle > add_vehicle_to_map(std::unique_ptr< vehicle > veh, bool merge_wrecks)
Takes a vehicle already created with new and attempts to place it on the map, checking for collisions...
Definition: mapgen.cpp:5702
void add_vehicle_to_cache(vehicle *)
Definition: map.cpp:330
std::vector< std::unique_ptr< vehicle > > vehicles
Vehicles on this submap (their (0,0) point is on this submap).
Definition: submap.h:218
tripoint sm_pos
Submap coordinates of the currently loaded submap (see game::m) that contains this vehicle.
Definition: vehicle.h:1926
point ms_to_sm_remain(int &x, int &y)
@ Warn
Warning (default: enabled).
#define dbg(x)
Definition: mapgen.cpp:99
bool move(avatar &you, map &m, const tripoint &d)
constexpr double to_degrees(const units::angle v)
Definition: units_angle.h:36
static constexpr point point_zero
Definition: point.h:260
std::string string_format(std::string_view format, Args &&...args)
Simple wrapper over string_formatter::parse.
constexpr point xy() const
Definition: point.h:206
std::string to_string() const
Definition: point.cpp:34

References add_vehicle_to_cache(), add_vehicle_to_map(), dbg, debugmsg, get_cache(), get_submap_at_grid(), inbounds(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), ms_to_sm_remain(), point_zero, vehicle::sm_pos, string_format(), units::to_degrees(), tripoint::to_string(), type, submap::vehicles, Warn, tripoint::xy(), and tripoint::z.

◆ add_vehicle() [4/4]

vehicle * map::add_vehicle ( const vproto_id type,
point  p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5645 of file mapgen.cpp.

5647{
5648 return add_vehicle( type, tripoint( p, abs_sub.z ), dir, veh_fuel, veh_status, merge_wrecks );
5649}

References abs_sub, add_vehicle(), type, and tripoint::z.

◆ add_vehicle_to_cache()

void map::add_vehicle_to_cache ( vehicle veh)

Definition at line 330 of file map.cpp.

331{
332 if( veh == nullptr ) {
333 debugmsg( "Tried to add null vehicle to cache" );
334 return;
335 }
336
337 // Get parts
338 for( const vpart_reference &vpr : veh->get_all_parts() ) {
339 if( vpr.part().removed ) {
340 continue;
341 }
342 const tripoint p = veh->global_part_pos3( vpr.part() );
343 level_cache &ch = get_cache( p.z );
344 ch.veh_in_active_range = true;
345 ch.veh_cached_parts[p] = std::make_pair( veh, static_cast<int>( vpr.part_index() ) );
346 if( inbounds( p ) ) {
347 ch.veh_exists_at[p.x][p.y] = true;
348 }
349 }
350
352}
bool last_full_vehicle_list_dirty
Definition: map.h:1985
vehicle_part_range get_all_parts() const
Yields a range containing all parts (including broken ones) that can be iterated over.
Definition: vehicle.cpp:7074
tripoint global_part_pos3(const int &index) const
Get the coordinates of the studied part of the vehicle.
Definition: vehicle.cpp:3287
This is a wrapper over a vehicle pointer and a reference to a part of it.
bool veh_in_active_range
Definition: map.h:354
bool veh_exists_at[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:355
std::map< tripoint, std::pair< vehicle *, int > > veh_cached_parts
Definition: map.h:356

References debugmsg, vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), last_full_vehicle_list_dirty, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_vehicle(), veh_interact::complete_vehicle(), displace_vehicle(), construct::done_vehicle(), loadn(), vehicle::part_removal_cleanup(), and reset_vehicle_cache().

◆ add_vehicle_to_map()

std::unique_ptr< vehicle > map::add_vehicle_to_map ( std::unique_ptr< vehicle veh,
bool  merge_wrecks 
)
private

Takes a vehicle already created with new and attempts to place it on the map, checking for collisions.

If the vehicle can't be placed, returns NULL, otherwise returns a pointer to the placed vehicle, which may not necessarily be the one passed in (if wreckage is created by fusing cars).

Parameters
vehThe vehicle to place on the map.
merge_wrecksWhether crashed vehicles become part of each other
Returns
The vehicle that was finally placed.

Definition at line 5702 of file mapgen.cpp.

5704{
5705 //We only want to check once per square, so loop over all structural parts
5706 std::vector<int> frame_indices = veh->all_parts_at_location( "structure" );
5707
5708 //Check for boat type vehicles that should be placeable in deep water
5709 const bool can_float = size( veh->get_avail_parts( "FLOATS" ) ) > 2;
5710
5711 //When hitting a wall, only smash the vehicle once (but walls many times)
5712 bool needs_smashing = false;
5713
5714 veh->attach();
5715 veh->refresh_position();
5716
5717 for( std::vector<int>::const_iterator part = frame_indices.begin();
5718 part != frame_indices.end(); part++ ) {
5719 const auto p = veh->global_part_pos3( *part );
5720
5721 //Don't spawn anything in water
5722 if( has_flag_ter( TFLAG_DEEP_WATER, p ) && !can_float ) {
5723 return nullptr;
5724 }
5725
5726 // Don't spawn shopping carts on top of another vehicle or other obstacle.
5727 if( veh->type == vproto_id( "shopping_cart" ) ) {
5728 if( veh_at( p ) || impassable( p ) ) {
5729 return nullptr;
5730 }
5731 }
5732
5733 //For other vehicles, simulate collisions with (non-shopping cart) stuff
5734 vehicle *const other_veh = veh_pointer_or_null( veh_at( p ) );
5735 if( other_veh != nullptr && other_veh->type != vproto_id( "shopping_cart" ) ) {
5736 if( !merge_wrecks ) {
5737 return nullptr;
5738 }
5739
5740 // Hard wreck-merging limit: 200 tiles
5741 // Merging is slow for big vehicles which lags the mapgen
5742 if( frame_indices.size() + other_veh->all_parts_at_location( "structure" ).size() > 200 ) {
5743 return nullptr;
5744 }
5745
5746 /* There's a vehicle here, so let's fuse them together into wreckage and
5747 * smash them up. It'll look like a nasty collision has occurred.
5748 * Trying to do a local->global->local conversion would be a major
5749 * headache, so instead, let's make another vehicle whose (0, 0) point
5750 * is the (0, 0) of the existing vehicle, convert the coordinates of both
5751 * vehicles into global coordinates, find the distance between them and
5752 * p and then install them that way.
5753 * Create a vehicle with type "null" so it starts out empty. */
5754 auto wreckage = std::make_unique<vehicle>();
5755 wreckage->pos = other_veh->pos;
5756 wreckage->sm_pos = other_veh->sm_pos;
5757
5758 //Where are we on the global scale?
5759 const tripoint global_pos = wreckage->global_pos3();
5760
5761 for( const vpart_reference &vpr : veh->get_all_parts() ) {
5762 const tripoint part_pos = veh->global_part_pos3( vpr.part() ) - global_pos;
5763 // TODO: change mount points to be tripoint
5764 wreckage->install_part( part_pos.xy(), vpr.part() );
5765 }
5766
5767 for( const vpart_reference &vpr : other_veh->get_all_parts() ) {
5768 const tripoint part_pos = other_veh->global_part_pos3( vpr.part() ) - global_pos;
5769 wreckage->install_part( part_pos.xy(), vpr.part() );
5770
5771 }
5772
5773 wreckage->name = _( "Wreckage" );
5774
5775 // Now get rid of the old vehicles
5776 std::unique_ptr<vehicle> old_veh = detach_vehicle( other_veh );
5777 // Failure has happened here when caches are corrupted due to bugs.
5778 // Add an assertion to avoid null-pointer dereference later.
5779 assert( old_veh );
5780
5781 // Try again with the wreckage
5782 std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( wreckage ), true );
5783 if( new_veh != nullptr ) {
5784 new_veh->smash( *this );
5785 return new_veh;
5786 }
5787
5788 // If adding the wreck failed, we want to restore the vehicle we tried to merge with
5789 add_vehicle_to_map( std::move( old_veh ), false );
5790 return nullptr;
5791
5792 } else if( impassable( p ) ) {
5793 if( !merge_wrecks ) {
5794 return nullptr;
5795 }
5796
5797 // There's a wall or other obstacle here; destroy it
5798 destroy( p, true );
5799
5800 // Some weird terrain, don't place the vehicle
5801 if( impassable( p ) ) {
5802 return nullptr;
5803 }
5804
5805 needs_smashing = true;
5806 }
5807 }
5808
5809 if( needs_smashing ) {
5810 veh->smash( *this );
5811 }
5812
5813 return veh;
5814}
void destroy(const tripoint &p, bool silent=false)
Keeps bashing a square until it can't be bashed anymore.
Definition: map.cpp:3733
std::unique_ptr< vehicle > detach_vehicle(vehicle *veh)
Definition: map.cpp:413
bool has_flag_ter(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2393
point pos
Position of the vehicle inside the submap that contains the vehicle.
Definition: vehicle.h:1941
vproto_id type
Type of the vehicle as it was spawned.
Definition: vehicle.h:1880
std::vector< int > all_parts_at_location(const std::string &location) const
Returns all parts in the vehicle that exist in the given location slot.
Definition: vehicle.cpp:2782
@ TFLAG_DEEP_WATER
Definition: mapdata.h:301
const size_t size
Definition: om_direction.h:27
#define _(msg)
Definition: translations.h:116
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, add_vehicle_to_map(), vehicle::all_parts_at_location(), destroy(), detach_vehicle(), vehicle::get_all_parts(), vehicle::global_part_pos3(), has_flag_ter(), impassable(), avatar_action::move(), vehicle::pos, om_direction::size, vehicle::sm_pos, TFLAG_DEEP_WATER, vehicle::type, veh_at(), veh_pointer_or_null(), and tripoint::xy().

Referenced by add_vehicle(), and add_vehicle_to_map().

◆ adjust_radiation() [1/2]

void map::adjust_radiation ( const tripoint p,
int  delta 
)

Increment the radiation in the given tile by the given delta (decrement it if delta is negative)

Definition at line 4155 of file map.cpp.

4156{
4157 if( !inbounds( p ) ) {
4158 return;
4159 }
4160
4161 point l;
4162 submap *const current_submap = get_submap_at( p, l );
4163
4164 int current_radiation = current_submap->get_radiation( l );
4165 current_submap->set_radiation( l, current_radiation + delta );
4166}
void set_radiation(point p, const int radiation)
Definition: submap.h:116
int get_radiation(point p) const
Definition: submap.h:112

References submap::get_radiation(), get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by computer_session::action_irradiator(), adjust_radiation(), MapExtras::mx_crater(), MapExtras::mx_portal_in(), process_fields_in_submap(), and Character::suffer_from_radiation().

◆ adjust_radiation() [2/2]

void map::adjust_radiation ( point  p,
const int  delta 
)
inline

Definition at line 1164 of file map.h.

1164 {
1165 adjust_radiation( tripoint( p, abs_sub.z ), delta );
1166 }
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4155

References abs_sub, adjust_radiation(), and tripoint::z.

◆ ambient_light_at()

float map::ambient_light_at ( const tripoint p) const

Definition at line 681 of file lightmap.cpp.

682{
683 if( !inbounds( p ) ) {
684 return 0.0f;
685 }
686
687 return get_cache_ref( p.z ).lm[p.x][p.y].max();
688}
const level_cache & get_cache_ref(int zlev) const
Definition: map.h:2001
float max() const
Definition: shadowcasting.h:45
four_quadrants lm[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:314

References get_cache_ref(), inbounds(), level_cache::lm, four_quadrants::max(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_character_light(), game::print_terrain_info(), and Creature::sees().

◆ apparent_light_at()

lit_level map::apparent_light_at ( const tripoint p,
const visibility_variables cache 
) const

Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc.

Parameters
pThe tile on this map to draw.
cacheCurrently cached visibility parameters

Definition at line 764 of file lightmap.cpp.

765{
766 const int dist = rl_dist( g->u.pos(), p );
767
768 // Clairvoyance overrides everything.
769 if( dist <= cache.u_clairvoyance ) {
770 return lit_level::BRIGHT;
771 }
772 const auto &map_cache = get_cache_ref( p.z );
773 const apparent_light_info a = apparent_light_helper( map_cache, p );
774
775 // Unimpaired range is an override to strictly limit vision range based on various conditions,
776 // but the player can still see light sources.
777 if( dist > g->u.unimpaired_range() ) {
778 if( !a.obstructed && map_cache.sm[p.x][p.y] > 0.0 ) {
780 } else {
781 return lit_level::DARK;
782 }
783 }
784 if( a.obstructed ) {
785 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
786 if( a.apparent_light > cache.g_light_level ) {
787 // This represents too hazy to see detail,
788 // but enough light getting through to illuminate.
790 } else {
791 // If it's not brighter than the surroundings, it just ends up shadowy.
792 return lit_level::LOW;
793 }
794 } else {
795 return lit_level::BLANK;
796 }
797 }
798 // Then we just search for the light level in descending order.
799 if( a.apparent_light > LIGHT_SOURCE_BRIGHT || map_cache.sm[p.x][p.y] > 0.0 ) {
800 return lit_level::BRIGHT;
801 }
802 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
803 return lit_level::LIT;
804 }
805 if( a.apparent_light >= cache.vision_threshold ) {
806 return lit_level::LOW;
807 } else {
808 return lit_level::BLANK;
809 }
810}
static apparent_light_info apparent_light_helper(const level_cache &map_cache, const tripoint &p)
Helper function for light claculation; exposed here for map editor.
Definition: lightmap.cpp:702
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
static constexpr float LIGHT_SOURCE_BRIGHT
Definition: lightmap.h:9
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
constexpr double a
Definition: magic.cpp:1030
float vision_threshold
Definition: map.h:128
int u_clairvoyance
Definition: map.h:127

References a, apparent_light_helper(), BLANK, BRIGHT, BRIGHT_ONLY, DARK, g, visibility_variables::g_light_level, get_cache_ref(), LIGHT_AMBIENT_LIT, LIGHT_SOURCE_BRIGHT, LIT, LOW, rl_dist(), visibility_variables::u_clairvoyance, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw_look_around_cursor(), game::print_all_tile_info(), editmap::update_view_with_help(), and update_visibility_cache().

◆ apparent_light_helper()

map::apparent_light_info map::apparent_light_helper ( const level_cache map_cache,
const tripoint p 
)
static

Helper function for light claculation; exposed here for map editor.

Definition at line 702 of file lightmap.cpp.

704{
705 const float vis = std::max( map_cache.seen_cache[p.x][p.y], map_cache.camera_cache[p.x][p.y] );
706 const bool obstructed = vis <= LIGHT_TRANSPARENCY_SOLID + 0.1;
707
708 auto is_opaque = [&map_cache]( point p ) {
709 return map_cache.transparency_cache[p.x][p.y] <= LIGHT_TRANSPARENCY_SOLID &&
710 get_player_character().pos().xy() != p;
711 };
712
713 const bool p_opaque = is_opaque( p.xy() );
714 float apparent_light;
715
716 if( p_opaque && vis > 0 ) {
717 // This is the complicated case. We want to check which quadrants the
718 // player can see the tile from, and only count light values from those
719 // quadrants.
720 struct offset_and_quadrants {
721 point offset;
722 std::array<quadrant, 2> quadrants;
723 };
724 static constexpr std::array<offset_and_quadrants, 8> adjacent_offsets = {{
733 }
734 };
735
736 four_quadrants seen_from( 0 );
737 for( const offset_and_quadrants &oq : adjacent_offsets ) {
738 const point neighbour = p.xy() + oq.offset;
739
740 if( !lightmap_boundaries.contains( neighbour ) ) {
741 continue;
742 }
743 if( is_opaque( neighbour ) ) {
744 continue;
745 }
746 if( map_cache.seen_cache[neighbour.x][neighbour.y] == 0 &&
747 map_cache.camera_cache[neighbour.x][neighbour.y] == 0 ) {
748 continue;
749 }
750 // This is a non-opaque visible neighbour, so count visibility from the relevant
751 // quadrants
752 seen_from[oq.quadrants[0]] = vis;
753 seen_from[oq.quadrants[1]] = vis;
754 }
755 apparent_light = ( seen_from * map_cache.lm[p.x][p.y] ).max();
756 } else {
757 // This is the simple case, for a non-opaque tile light from all
758 // directions is equivalent
759 apparent_light = vis * map_cache.lm[p.x][p.y].max();
760 }
761 return { obstructed, apparent_light };
762}
const half_open_rectangle< point > lightmap_boundaries(lightmap_boundary_min, lightmap_boundary_max)
static constexpr float LIGHT_TRANSPARENCY_SOLID
Transparency 101: Transparency usually ranges between 0.038 (open air) and 0.38 (regular smoke).
Definition: lightmap.h:32
static constexpr point point_south_west
Definition: point.h:267
static constexpr point point_west
Definition: point.h:268
static constexpr point point_north_east
Definition: point.h:263
static constexpr point point_north_west
Definition: point.h:269
static constexpr point point_south_east
Definition: point.h:265
static constexpr point point_south
Definition: point.h:266
static constexpr point point_north
Definition: point.h:262
static constexpr point point_east
Definition: point.h:264
float seen_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:343
float transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:332
float camera_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:347
int y
Definition: point.h:39
int x
Definition: point.h:38

References level_cache::camera_cache, get_player_character(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, four_quadrants::max(), NE, NW, point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, point_west, Character::pos(), SE, level_cache::seen_cache, SW, level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by apparent_light_at(), pl_sees(), and editmap::update_view_with_help().

◆ apply_character_light()

void map::apply_character_light ( Character p)
protected

Definition at line 262 of file lightmap.cpp.

263{
264 if( p.has_effect( effect_onfire ) ) {
265 apply_light_source( p.pos(), 8 );
266 } else if( p.has_effect( effect_haslight ) ) {
267 apply_light_source( p.pos(), 4 );
268 }
269
270 const float held_luminance = p.active_light();
271 if( held_luminance > LIGHT_AMBIENT_LOW ) {
272 apply_light_source( p.pos(), held_luminance );
273 }
274
275 if( held_luminance >= 4 && held_luminance > ambient_light_at( p.pos() ) - 0.5f ) {
276 p.add_effect( effect_haslight, 1_turns );
277 }
278}
float active_light() const
Returns character luminosity based on the brightest active item they are carrying.
Definition: character.cpp:6290
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:987
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1186
void apply_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:1749
float ambient_light_at(const tripoint &p) const
Definition: lightmap.cpp:681
static const efftype_id effect_haslight("haslight")
static const efftype_id effect_onfire("onfire")
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14

References Character::active_light(), Creature::add_effect(), ambient_light_at(), apply_light_source(), effect_haslight, effect_onfire, Creature::has_effect(), LIGHT_AMBIENT_LOW, and Character::pos().

Referenced by generate_lightmap().

◆ apply_directional_light()

void map::apply_directional_light ( const tripoint p,
int  direction,
float  luminance 
)
private

Definition at line 1830 of file lightmap.cpp.

1831{
1832 const point p2( p.xy() );
1833
1834 auto &cache = get_cache( p.z );
1835 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1836 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1837 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1838
1839 if( direction == 90 ) {
1842 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1845 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1846 } else if( direction == 0 ) {
1849 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1852 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1853 } else if( direction == 270 ) {
1856 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1859 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1860 } else if( direction == 180 ) {
1863 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1866 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1867 }
1868}
static constexpr int MAPSIZE_Y
static constexpr int MAPSIZE_X
static float light_from_lookup(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1743
static bool light_check(const float &transparency, const float &intensity)
Definition: lightmap.cpp:1738
static float light_calc(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1731
void castLightWithLookup(Out(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const T(&input_array)[MAPSIZE_X][MAPSIZE_Y], const diagonal_blocks(&blocked_array)[MAPSIZE_X][MAPSIZE_Y], const point &offset, int offsetDistance, T numerator=VISIBILITY_FULL, int row=1, float start=1.0f, float end=0.0f, T cumulative_transparency=LIGHT_TRANSPARENCY_OPEN_AIR)
Definition: lightmap.cpp:1382
direction
Definition: line.h:39
void update_light_quadrants(four_quadrants &update, const float &new_value, quadrant q)
Definition: shadowcasting.h:97
float accumulate_transparency(const float &cumulative_transparency, const float &current_transparency, const int &distance)

References accumulate_transparency(), castLightWithLookup(), get_cache(), light_calc(), light_check(), light_from_lookup(), MAPSIZE_X, MAPSIZE_Y, update_light_quadrants(), tripoint::xy(), and tripoint::z.

Referenced by generate_lightmap().

◆ apply_faction_ownership()

void map::apply_faction_ownership ( point  p1,
point  p2,
const faction_id id 
)

Definition at line 5527 of file mapgen.cpp.

5528{
5529 for( const tripoint &p : points_in_rectangle( tripoint( p1, abs_sub.z ), tripoint( p2,
5530 abs_sub.z ) ) ) {
5531 auto items = i_at( p.xy() );
5532 for( item &elem : items ) {
5533 elem.set_owner( id );
5534 }
5535 vehicle *source_veh = veh_pointer_or_null( veh_at( p ) );
5536 if( source_veh ) {
5537 if( !source_veh->has_owner() ) {
5538 source_veh->set_owner( id );
5539 }
5540 }
5541 }
5542}
tripoint_range< tripoint > points_in_rectangle(const tripoint &from, const tripoint &to) const
Definition: map.cpp:8722
bool has_owner() const
Definition: vehicle.h:845
void set_owner(const faction_id &new_owner)
Definition: vehicle.h:832

References abs_sub, vehicle::has_owner(), i_at(), points_in_rectangle(), vehicle::set_owner(), veh_at(), veh_pointer_or_null(), and tripoint::z.

Referenced by jmapgen_faction::apply().

◆ apply_light_arc()

void map::apply_light_arc ( const tripoint p,
units::angle  angle,
float  luminance,
units::angle  wideangle = 30_degrees 
)
private

Definition at line 1870 of file lightmap.cpp.

1872{
1873 if( luminance <= LIGHT_SOURCE_LOCAL ) {
1874 return;
1875 }
1876
1877 bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {};
1878
1880
1881 // Normalize (should work with negative values too)
1882 const units::angle wangle = wideangle / 2.0;
1883
1884 units::angle nangle = fmod( angle, 360_degrees );
1885
1886 tripoint end;
1887 int range = LIGHT_RANGE( luminance );
1888 calc_ray_end( nangle, range, p, end );
1889 apply_light_ray( lit, p, end, luminance );
1890
1891 tripoint test;
1892 calc_ray_end( wangle + nangle, range, p, test );
1893
1894 const float wdist = hypot( end.x - test.x, end.y - test.y );
1895 if( wdist <= 0.5 ) {
1896 return;
1897 }
1898
1899 // attempt to determine beam intensity required to cover all squares
1900 const units::angle wstep = ( wangle / ( wdist * M_SQRT2 ) );
1901
1902 // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter)
1903 for( units::angle ao = wstep; ao <= wangle; ao += wstep ) {
1904 if( trigdist ) {
1905 double fdist = ( ao * M_PI_2 ) / wangle;
1906 end.x = static_cast<int>(
1907 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle + ao ) );
1908 end.y = static_cast<int>(
1909 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle + ao ) );
1910 apply_light_ray( lit, p, end, luminance );
1911
1912 end.x = static_cast<int>(
1913 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle - ao ) );
1914 end.y = static_cast<int>(
1915 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle - ao ) );
1916 apply_light_ray( lit, p, end, luminance );
1917 } else {
1918 calc_ray_end( nangle + ao, range, p, end );
1919 apply_light_ray( lit, p, end, luminance );
1920 calc_ray_end( nangle - ao, range, p, end );
1921 apply_light_ray( lit, p, end, luminance );
1922 }
1923 }
1924}
bool trigdist
Circular distances.
void apply_light_ray(bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
Definition: lightmap.cpp:1926
static constexpr int LIGHTMAP_CACHE_Y
Definition: lightmap.cpp:49
static constexpr int LIGHTMAP_CACHE_X
Definition: lightmap.cpp:48
static constexpr float LIGHT_SOURCE_LOCAL
Definition: lightmap.h:8
#define LIGHT_RANGE(b)
Definition: lightmap.h:41
void calc_ray_end(units::angle angle, const int range, const tripoint &p, tripoint &out)
Definition: line.cpp:752
#define M_SQRT2
Definition: math_defines.h:29
#define M_PI_2
Definition: math_defines.h:25
quantity< double, angle_in_radians_tag > angle
Definition: units_angle.h:17
double sin(angle a)
Definition: units_angle.h:52
double cos(angle a)
Definition: units_angle.h:57
quantity< V, U > fmod(quantity< V, U > num, quantity< V, U > den)
Definition: units_def.h:142

References apply_light_ray(), apply_light_source(), calc_ray_end(), units::cos(), units::fmod(), LIGHT_RANGE, LIGHT_SOURCE_LOCAL, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, M_PI_2, M_SQRT2, units::sin(), trigdist, tripoint::x, and tripoint::y.

Referenced by add_light_from_items(), and generate_lightmap().

◆ apply_light_ray()

void map::apply_light_ray ( bool  lit[MAPSIZE_X][MAPSIZE_Y],
const tripoint s,
const tripoint e,
float  luminance 
)
private

Definition at line 1926 of file lightmap.cpp.

1928{
1929 point a( std::abs( e.x - s.x ) * 2, std::abs( e.y - s.y ) * 2 );
1930 point d( ( s.x < e.x ) ? 1 : -1, ( s.y < e.y ) ? 1 : -1 );
1931 point p( s.xy() );
1932
1933 quadrant quad = quadrant_from_x_y( d.x, d.y );
1934
1935 // TODO: Invert that z comparison when it's sane
1936 if( s.z != e.z || ( s.x == e.x && s.y == e.y ) ) {
1937 return;
1938 }
1939
1940 auto &lm = get_cache( s.z ).lm;
1941 auto &transparency_cache = get_cache( s.z ).transparency_cache;
1942
1943 float distance = 1.0;
1944 float transparency = LIGHT_TRANSPARENCY_OPEN_AIR;
1945 const float scaling_factor = static_cast<float>( rl_dist( s, e ) ) /
1946 static_cast<float>( square_dist( s, e ) );
1947 // TODO: [lightmap] Pull out the common code here rather than duplication
1948 if( a.x > a.y ) {
1949 int t = a.y - ( a.x / 2 );
1950 do {
1951 if( t >= 0 ) {
1952 p.y += d.y;
1953 t -= a.x;
1954 }
1955
1956 p.x += d.x;
1957 t += a.y;
1958
1959 // TODO: clamp coordinates to map bounds before this method is called.
1960 if( lightmap_boundaries.contains( p ) ) {
1961 float current_transparency = transparency_cache[p.x][p.y];
1962 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1963 if( !lit[p.x][p.y] ) {
1964 // Multiple rays will pass through the same squares so we need to record that
1965 lit[p.x][p.y] = true;
1966 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1967 quadrant q = is_opaque ? quad : quadrant::default_;
1968 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1969 }
1970 if( is_opaque ) {
1971 break;
1972 }
1973 // Cumulative average of the transparency values encountered.
1974 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1975 } else {
1976 break;
1977 }
1978
1979 distance += scaling_factor;
1980 } while( !( p.x == e.x && p.y == e.y ) );
1981 } else {
1982 int t = a.x - ( a.y / 2 );
1983 do {
1984 if( t >= 0 ) {
1985 p.x += d.x;
1986 t -= a.y;
1987 }
1988
1989 p.y += d.y;
1990 t += a.x;
1991
1992 if( lightmap_boundaries.contains( p ) ) {
1993 float current_transparency = transparency_cache[p.x][p.y];
1994 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1995 if( !lit[p.x][p.y] ) {
1996 // Multiple rays will pass through the same squares so we need to record that
1997 lit[p.x][p.y] = true;
1998 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1999 quadrant q = is_opaque ? quad : quadrant::default_;
2000 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
2001 }
2002 if( is_opaque ) {
2003 break;
2004 }
2005 // Cumulative average of the transparency values encountered.
2006 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
2007 } else {
2008 break;
2009 }
2010
2011 distance += scaling_factor;
2012 } while( !( p.x == e.x && p.y == e.y ) );
2013 }
2014}
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505
static constexpr quadrant quadrant_from_x_y(int x, int y)
Definition: lightmap.cpp:875
static float fastexp(float x)
Definition: lightmap.cpp:1715
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36
quadrant
Definition: shadowcasting.h:22

References a, default_, fastexp(), get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, quadrant_from_x_y(), rl_dist(), square_dist(), level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by apply_light_arc().

◆ apply_light_source()

void map::apply_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 1749 of file lightmap.cpp.

1750{
1751 auto &cache = get_cache( p.z );
1752 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1753 float ( &sm )[MAPSIZE_X][MAPSIZE_Y] = cache.sm;
1754 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1755 float ( &light_source_buffer )[MAPSIZE_X][MAPSIZE_Y] = cache.light_source_buffer;
1756 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1757
1758 const point p2( p.xy() );
1759
1760 if( inbounds( p ) ) {
1761 const float min_light = std::max( static_cast<float>( lit_level::LOW ), luminance );
1762 lm[p2.x][p2.y] = elementwise_max( lm[p2.x][p2.y], min_light );
1763 sm[p2.x][p2.y] = std::max( sm[p2.x][p2.y], luminance );
1764 }
1765 if( luminance <= lit_level::LOW ) {
1766 return;
1767 } else if( luminance <= lit_level::BRIGHT_ONLY ) {
1768 luminance = 1.49f;
1769 }
1770
1771 /* If we're a 5 luminance fire , we skip casting rays into ey && sx if we have
1772 neighboring fires to the north and west that were applied via light_source_buffer
1773 If there's a 1 luminance candle east in buffer, we still cast rays into ex since it's smaller
1774 If there's a 100 luminance magnesium flare south added via apply_light_source instead od
1775 add_light_source, it's unbuffered so we'll still cast rays into sy.
1776
1777 ey
1778 nnnNnnn
1779 w e
1780 w 5 +e
1781 sx W 5*1+E ex
1782 w ++++e
1783 w+++++e
1784 sssSsss
1785 sy
1786 */
1787 const int peer_inbounds = LIGHTMAP_CACHE_X - 1;
1788 bool north = ( p2.y != 0 && light_source_buffer[p2.x][p2.y - 1] < luminance );
1789 bool south = ( p2.y != peer_inbounds && light_source_buffer[p2.x][p2.y + 1] < luminance );
1790 bool east = ( p2.x != peer_inbounds && light_source_buffer[p2.x + 1][p2.y] < luminance );
1791 bool west = ( p2.x != 0 && light_source_buffer[p2.x - 1][p2.y] < luminance );
1792
1793 if( north ) {
1796 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1799 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1800 }
1801
1802 if( east ) {
1805 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1808 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1809 }
1810
1811 if( south ) {
1814 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1817 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1818 }
1819
1820 if( west ) {
1823 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1826 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1827 }
1828}
constexpr scale sm
Definition: coordinates.h:31

References accumulate_transparency(), BRIGHT_ONLY, castLightWithLookup(), get_cache(), inbounds(), light_calc(), light_check(), light_from_lookup(), LIGHTMAP_CACHE_X, LOW, MAPSIZE_X, MAPSIZE_Y, coords::sm, update_light_quadrants(), point::x, tripoint::xy(), point::y, and tripoint::z.

Referenced by apply_character_light(), apply_light_arc(), and generate_lightmap().

◆ apply_vision_transparency_cache()

void map::apply_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1466 of file lightmap.cpp.

1468{
1469 level_cache &map_cache = get_cache( target_z );
1470 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1471 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1472
1473 int i = 0;
1474 for( point adjacent : eight_adjacent_offsets ) {
1475 const tripoint p = center + adjacent;
1476 if( !inbounds( p ) ) {
1477 continue;
1478 }
1479 vision_restore_cache[i] = transparency_cache[p.x][p.y];
1481 transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_SOLID;
1483
1485 adjacent ) == four_diagonal_offsets.end() ) {
1486 debugmsg( "Hidden tile not on a diagonal" );
1487 continue;
1488 }
1489
1490 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1491 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1492 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1493 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1494
1495 //We only set the restore cache if we actually flip the bit
1496 blocked_restore_cache[i] = !relevant_blocked;
1497
1498 relevant_blocked = true;
1499 }
1500 i++;
1501 }
1502 vision_restore_cache[8] = transparency_cache[center.x][center.y];
1503}
vision_adjustment vision_transparency_cache[8]
Definition: map.h:1786
@ VISION_ADJUST_HIDDEN
Definition: lightmap.h:79
@ VISION_ADJUST_SOLID
Definition: lightmap.h:78
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
static constexpr std::array< point, 8 > eight_adjacent_offsets
Definition: point.h:352
static constexpr std::array< point, 4 > four_diagonal_offsets
Definition: point.h:348
diagonal_blocks vehicle_obscured_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:336

References center, debugmsg, eight_adjacent_offsets, detail::find(), four_diagonal_offsets, get_cache(), inbounds(), LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, level_cache::transparency_cache, level_cache::vehicle_obscured_cache, VISION_ADJUST_HIDDEN, VISION_ADJUST_SOLID, vision_transparency_cache, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ bash()

bash_results map::bash ( const tripoint p,
int  str,
bool  silent = false,
bool  destroy = false,
bool  bash_floor = false,
const vehicle bashing_vehicle = nullptr 
)

Returns a pair where first is whether anything was smashed and second is if it was destroyed.

Parameters
pWhere to bash
strHow hard to bash
silentDon't produce any sound
destroyDestroys some otherwise unbashable tiles
bash_floorAllow bashing the floor and the tile that supports it
bashing_vehicleVehicle that should NOT be bashed (because it is doing the bashing)

Definition at line 3622 of file map.cpp.

3625{
3626 bash_params bsh{
3627 str, silent, destroy, bash_floor, static_cast<float>( rng_float( 0, 1.0f ) ), false, true
3628 };
3630 if( !inbounds( p ) ) {
3631 return result;
3632 }
3633
3634 bool bashed_sealed = false;
3635 if( has_flag( "SEALED", p ) ) {
3636 result |= bash_ter_furn( p, bsh );
3637 bashed_sealed = true;
3638 }
3639
3640 result |= bash_field( p, bsh );
3641
3642 // Don't bash items inside terrain/furniture with SEALED flag
3643 if( !bashed_sealed ) {
3644 result |= bash_items( p, bsh );
3645 }
3646 // Don't bash the vehicle doing the bashing
3647 const vehicle *veh = veh_pointer_or_null( veh_at( p ) );
3648 if( veh != nullptr && veh != bashing_vehicle ) {
3649 result |= bash_vehicle( p, bsh );
3650 }
3651
3652 // If we still didn't bash anything solid (a vehicle) or a tile with SEALED flag, bash ter/furn
3653 if( !result.bashed_solid && !bashed_sealed ) {
3654 result |= bash_ter_furn( p, bsh );
3655 }
3656
3657 return result;
3658}
bash_results bash_field(const tripoint &p, const bash_params &params)
Definition: map.cpp:3712
bash_results bash_items(const tripoint &p, const bash_params &params)
Definition: map.cpp:3660
bash_results bash_vehicle(const tripoint &p, const bash_params &params)
Definition: map.cpp:3694
bash_results bash_ter_furn(const tripoint &p, const bash_params &params)
Definition: map.cpp:3498
double rng_float(double lo, double hi)
Definition: rng.cpp:28
@ silent
Definition: weather_type.h:56

References bash_field(), bash_items(), bash_ter_furn(), bash_vehicle(), destroy(), has_flag(), inbounds(), rng_float(), silent, veh_at(), and veh_pointer_or_null().

Referenced by Character::activate_bionic(), jmapgen_setmap::apply(), spell_effect::bash(), bash_furn_success(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), batter(), destroy(), destroy_furn(), drop_furniture(), drop_items(), game::fling_creature(), is_bashable(), game::knockback(), explosion_handler::legacy_blast(), explosion_handler::legacy_shrapnel(), npc::move_to(), vehicle::part_collision(), explosion_handler::ExplosionProcess::project_shrapnel(), Character::reach_attack(), route(), scatter_chunks(), shoot(), mattack::shriek_stun(), smash(), and valid_move().

◆ bash_field()

bash_results map::bash_field ( const tripoint p,
const bash_params params 
)

Definition at line 3712 of file map.cpp.

3713{
3715 if( get_field( p, fd_web ) != nullptr ) {
3716 result.did_bash = true;
3717 result.bashed_solid = true; // To prevent bashing furniture/vehicles
3718 remove_field( p, fd_web );
3719 }
3720
3721 return result;
3722}
void remove_field(const tripoint &p, const field_type_id &field_to_remove)
Remove field entry at xy, ignored if the field entry is not present.
Definition: map.cpp:5563
field_type_id fd_web
Definition: field_type.cpp:340

References fd_web, get_field(), and remove_field().

Referenced by bash(), and explosion_handler::ExplosionProcess::blast_tile().

◆ bash_furn_success()

bash_results map::bash_furn_success ( const tripoint p,
const bash_params params 
)

Definition at line 3398 of file map.cpp.

3399{
3401 const auto &furnid = furn( p ).obj();
3402 const map_bash_info &bash = furnid.bash;
3403
3404
3405 if( has_flag_furn( "FUNGUS", p ) ) {
3406 fungal_effects( *g, *this ).create_spores( p );
3407 }
3408 if( has_flag_furn( "MIGO_NERVE", p ) ) {
3409 map_funcs::migo_nerve_cage_removal( *this, p, true );
3410 }
3411 std::string soundfxvariant = furnid.id.str();
3412 const bool tent = !bash.tent_centers.empty();
3413
3414 // Special code to collapse the tent if destroyed
3415 if( tent ) {
3416 // Get ids of possible centers
3417 std::set<furn_id> centers;
3418 for( const auto &cur_id : bash.tent_centers ) {
3419 if( cur_id.is_valid() ) {
3420 centers.insert( cur_id );
3421 }
3422 }
3423
3424 std::optional<std::pair<tripoint, furn_id>> tentp;
3425
3426 // Find the center of the tent
3427 // First check if we're not currently bashing the center
3428 if( centers.count( furn( p ) ) > 0 ) {
3429 tentp.emplace( p, furn( p ) );
3430 } else {
3431 for( const tripoint &pt : points_in_radius( p, bash.collapse_radius ) ) {
3432 const furn_id &f_at = furn( pt );
3433 // Check if we found the center of the current tent
3434 if( centers.count( f_at ) > 0 ) {
3435 tentp.emplace( pt, f_at );
3436 break;
3437 }
3438 }
3439 }
3440 // Didn't find any tent center, wreck the current tile
3441 if( !tentp ) {
3443 furn_set( p, bash.furn_set );
3444 } else {
3445 // Take the tent down
3446 const int rad = tentp->second.obj().bash.collapse_radius;
3447 for( const tripoint &pt : points_in_radius( tentp->first, rad ) ) {
3448 const furn_id frn = furn( pt );
3449 if( frn == f_null ) {
3450 continue;
3451 }
3452
3453 const map_bash_info &recur_bash = frn.obj().bash;
3454 // Check if we share a center type and thus a "tent type"
3455 for( const auto &cur_id : recur_bash.tent_centers ) {
3456 if( centers.count( cur_id.id() ) > 0 ) {
3457 // Found same center, wreck current tile
3459 furn_set( pt, recur_bash.furn_set );
3460 break;
3461 }
3462 }
3463 }
3464 }
3465 soundfxvariant = "smash_cloth";
3466 } else {
3467 furn_set( p, bash.furn_set );
3468 for( item &it : i_at( p ) ) {
3469 it.on_drop( p, *this );
3470 }
3471 // HACK: Hack alert.
3472 // Signs have cosmetics associated with them on the submap since
3473 // furniture can't store dynamic data to disk. To prevent writing
3474 // mysteriously appearing for a sign later built here, remove the
3475 // writing from the submap.
3476 delete_signage( p );
3477 }
3478
3479 if( !tent ) {
3481 }
3482
3483 if( !bash.sound.empty() && !params.silent ) {
3484 static const std::string soundfxid = "smash_success";
3485 int sound_volume = get_sound_volume( bash );
3486 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3487 soundfxid, soundfxvariant );
3488 }
3489
3490 if( bash.explosive > 0 ) {
3491 // TODO implement if the player triggered the explosive furniture
3492 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3493 }
3494
3495 return result;
3496}
void create_spores(const tripoint &p, Creature *origin=nullptr)
Makes spores at p.
bool has_flag_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2398
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3622
std::vector< item * > spawn_items(const tripoint &p, const std::vector< item > &new_items)
Definition: map.cpp:4260
void furn_set(const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
Sets the furniture at given position.
Definition: map.cpp:1424
void delete_signage(const tripoint &p) const
Definition: map.cpp:4119
static int get_sound_volume(const map_bash_info &bash)
Definition: map.cpp:3260
furn_id f_null
Definition: mapdata.cpp:1097
void explosion(const tripoint &p, Creature *source, float power, float factor, bool fire, int legacy_casing_mass, float)
Legacy explosion function.
Definition: explosion.cpp:1079
ItemList items_from(const item_group_id &group_id, const time_point &birthday)
Create items from the given group.
Definition: item_group.cpp:574
void migo_nerve_cage_removal(map &m, const tripoint &p, bool spawn_damaged)
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:177
@ rad
Must be irradiated/in irradiated tile.
bool silent
Definition: map.h:136
std::vector< furn_str_id > tent_centers
Definition: mapdata.h:100
item_group_id drop_group
Definition: mapdata.h:86
furn_str_id furn_set
Definition: mapdata.h:98
map_bash_info bash
Definition: mapdata.h:346

References bash(), map_data_common_t::bash, sounds::combat, fungal_effects::create_spores(), delete_signage(), map_bash_info::drop_group, explosion_handler::explosion(), f_null, furn(), furn_set(), map_bash_info::furn_set, g, get_sound_volume(), has_flag_furn(), i_at(), item_group::items_from(), map_funcs::migo_nerve_cage_removal(), int_id< T >::obj(), points_in_radius(), rad, bash_params::silent, sounds::sound(), spawn_items(), map_bash_info::tent_centers, and calendar::turn.

Referenced by bash_ter_furn().

◆ bash_items()

bash_results map::bash_items ( const tripoint p,
const bash_params params 
)

Definition at line 3660 of file map.cpp.

3661{
3663 if( !has_items( p ) ) {
3664 return result;
3665 }
3666
3667 std::vector<item> smashed_contents;
3668 auto bashed_items = i_at( p );
3669 bool smashed_glass = false;
3670 for( auto bashed_item = bashed_items.begin(); bashed_item != bashed_items.end(); ) {
3671 // the check for active suppresses Molotovs smashing themselves with their own explosion
3672 if( bashed_item->made_of( material_id( "glass" ) ) && !bashed_item->active && one_in( 2 ) ) {
3673 result.did_bash = true;
3674 smashed_glass = true;
3675 for( const item *bashed_content : bashed_item->contents.all_items_top() ) {
3676 smashed_contents.push_back( item( *bashed_content ) );
3677 }
3678 bashed_item = bashed_items.erase( bashed_item );
3679 } else {
3680 ++bashed_item;
3681 }
3682 }
3683 // Now plunk in the contents of the smashed items.
3684 spawn_items( p, smashed_contents );
3685
3686 // Add a glass sound even when something else also breaks
3687 if( smashed_glass && !params.silent ) {
3688 sounds::sound( p, 12, sounds::sound_t::combat, _( "glass shattering" ), false,
3689 "smash_success", "smash_glass_contents" );
3690 }
3691 return result;
3692}
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
item_contents contents
Definition: item.h:2158
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4868

References _, item_contents::all_items_top(), sounds::combat, item::contents, has_items(), i_at(), one_in(), bash_params::silent, sounds::sound(), and spawn_items().

Referenced by bash(), and explosion_handler::ExplosionProcess::blast_tile().

◆ bash_rating() [1/2]

int map::bash_rating ( const int  str,
point  p 
) const
inline

Definition at line 992 of file map.h.

992 {
993 return bash_rating( str, tripoint( p, abs_sub.z ) );
994 }
int bash_rating(int str, const tripoint &p, bool allow_floor=false) const
Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement...
Definition: map.cpp:2569

References abs_sub, bash_rating(), and tripoint::z.

◆ bash_rating() [2/2]

int map::bash_rating ( int  str,
const tripoint p,
bool  allow_floor = false 
) const

Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down.

-1 means the square is not bashable

Definition at line 2569 of file map.cpp.

2570{
2571 if( !inbounds( p ) ) {
2572 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2573 return -1;
2574 }
2575
2576 if( str <= 0 ) {
2577 return -1;
2578 }
2579
2580 const furn_t &furniture = furn( p ).obj();
2581 const ter_t &terrain = ter( p ).obj();
2582 const optional_vpart_position vp = veh_at( p );
2583 vehicle *const veh = vp ? &vp->vehicle() : nullptr;
2584 const int part = vp ? vp->part_index() : -1;
2585 return bash_rating_internal( str, furniture, terrain, allow_floor, veh, part );
2586}
int bash_rating_internal(int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
Definition: map.cpp:2461

References bash_rating_internal(), dbg, furn(), furniture, inbounds(), int_id< T >::obj(), ter(), terrain, veh_at(), and Warn.

Referenced by bash_rating(), npc::can_move_to(), monster::move(), and npc::move_to().

◆ bash_rating_internal()

int map::bash_rating_internal ( int  str,
const furn_t furniture,
const ter_t terrain,
bool  allow_floor,
const vehicle veh,
int  part 
) const
private
Strength determines what furniture can be smashed Strength determines what terrain can be smashed Strength increases smashing damage

Definition at line 2461 of file map.cpp.

2464{
2465 bool furn_smash = false;
2466 bool ter_smash = false;
2467 ///\EFFECT_STR determines what furniture can be smashed
2468 if( furniture.id && furniture.bash.str_max != -1 ) {
2469 furn_smash = true;
2470 ///\EFFECT_STR determines what terrain can be smashed
2471 } else if( terrain.bash.str_max != -1 && ( !terrain.bash.bash_below || allow_floor ) ) {
2472 ter_smash = true;
2473 }
2474
2475 if( veh != nullptr && vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part() ) {
2476 // Monsters only care about rating > 0, NPCs should want to path around cars instead
2477 return 2; // Should probably be a function of part hp (+armor on tile)
2478 }
2479
2480 int bash_min = 0;
2481 int bash_max = 0;
2482 if( furn_smash ) {
2483 bash_min = furniture.bash.str_min;
2484 bash_max = furniture.bash.str_max;
2485 } else if( ter_smash ) {
2486 bash_min = terrain.bash.str_min;
2487 bash_max = terrain.bash.str_max;
2488 } else {
2489 return -1;
2490 }
2491
2492 ///\EFFECT_STR increases smashing damage
2493 if( str < bash_min ) {
2494 return 0;
2495 } else if( str >= bash_max ) {
2496 return 10;
2497 }
2498
2499 int ret = ( 10 * ( str - bash_min ) ) / ( bash_max - bash_min );
2500 // Round up to 1, so that desperate NPCs can try to bash down walls
2501 return std::max( ret, 1 );
2502}
Reference to a position (a point) of the vehicle.

References furniture, cata::hash64_detail::ret, and terrain.

Referenced by bash_rating(), and route().

◆ bash_resistance() [1/2]

int map::bash_resistance ( const tripoint p,
bool  allow_floor = false 
) const

Returns min_str of the furniture or terrain at p.

Definition at line 2555 of file map.cpp.

2556{
2557 if( has_furn( p ) && furn( p ).obj().bash.str_min != -1 ) {
2558 return furn( p ).obj().bash.str_min;
2559 }
2560
2561 const auto &ter_bash = ter( p ).obj().bash;
2562 if( ter_bash.str_min != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2563 return ter_bash.str_min;
2564 }
2565
2566 return -1;
2567}
bool has_furn(const tripoint &p) const
Definition: map.cpp:1407
int str_min
Definition: mapdata.h:62

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_min, and ter().

Referenced by bash_resistance(), ranged::expected_coverage(), vehicle::part_collision(), rate_location(), smash(), and terrain_collision_data().

◆ bash_resistance() [2/2]

int map::bash_resistance ( point  p) const
inline

Definition at line 986 of file map.h.

986 {
987 return bash_resistance( tripoint( p, abs_sub.z ) );
988 }
int bash_resistance(const tripoint &p, bool allow_floor=false) const
Returns min_str of the furniture or terrain at p.
Definition: map.cpp:2555

References abs_sub, bash_resistance(), and tripoint::z.

◆ bash_strength() [1/2]

int map::bash_strength ( const tripoint p,
bool  allow_floor = false 
) const

Returns max_str of the furniture or terrain at p.

Definition at line 2541 of file map.cpp.

2542{
2543 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2544 return furn( p ).obj().bash.str_max;
2545 }
2546
2547 const auto &ter_bash = ter( p ).obj().bash;
2548 if( ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2549 return ter_bash.str_max;
2550 }
2551
2552 return -1;
2553}
int str_max
Definition: mapdata.h:64

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by bash_strength(), ranged::expected_coverage(), game::fling_creature(), and terrain_collision_data().

◆ bash_strength() [2/2]

int map::bash_strength ( point  p) const
inline

Definition at line 981 of file map.h.

981 {
982 return bash_strength( tripoint( p, abs_sub.z ) );
983 }
int bash_strength(const tripoint &p, bool allow_floor=false) const
Returns max_str of the furniture or terrain at p.
Definition: map.cpp:2541

References abs_sub, bash_strength(), and tripoint::z.

◆ bash_ter_furn()

bash_results map::bash_ter_furn ( const tripoint p,
const bash_params params 
)

Definition at line 3498 of file map.cpp.

3499{
3501 std::string soundfxvariant;
3502 const auto &ter_obj = ter( p ).obj();
3503 const auto &furn_obj = furn( p ).obj();
3504 bool smash_ter = false;
3505 const map_bash_info *bash = nullptr;
3506
3507 if( furn_obj.id && furn_obj.bash.str_max != -1 ) {
3508 bash = &furn_obj.bash;
3509 soundfxvariant = furn_obj.id.str();
3510 } else if( ter_obj.bash.str_max != -1 ) {
3511 bash = &ter_obj.bash;
3512 smash_ter = true;
3513 soundfxvariant = ter_obj.id.str();
3514 }
3515
3516 // Floor bashing check
3517 // Only allow bashing floors when we want to bash floors and we're in z-level mode
3518 // Unless we're destroying, then it gets a little weird
3519 if( smash_ter && bash->bash_below && ( !zlevels || !params.bash_floor ) ) {
3520 if( !params.destroy ) {
3521 smash_ter = false;
3522 bash = nullptr;
3523 } else if( !bash->ter_set && zlevels ) {
3524 // HACK: A hack for destroy && !bash_floor
3525 // We have to check what would we create and cancel if it is what we have now
3526 tripoint below( p.xy(), p.z - 1 );
3527 const auto roof = get_roof( below, false );
3528 if( roof == ter( p ) ) {
3529 smash_ter = false;
3530 bash = nullptr;
3531 }
3532 } else if( !bash->ter_set && ter( p ) == t_dirt ) {
3533 // As above, except for no-z-levels case
3534 smash_ter = false;
3535 bash = nullptr;
3536 }
3537 }
3538
3539 // TODO: what if silent is true?
3540 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3541 sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ),
3542 false, "environment", "alarm" );
3543 // Blame nearby player
3544 if( rl_dist( g->u.pos(), p ) <= 3 ) {
3545 g->events().send<event_type::triggers_alarm>( g->u.getID() );
3546 const point abs = ms_to_sm_copy( getabs( p.xy() ) );
3547 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0,
3548 tripoint( abs, p.z ) );
3549 }
3550 }
3551
3552 if( bash == nullptr || ( bash->destroy_only && !params.destroy ) ) {
3553 // Nothing bashable here
3554 if( impassable( p ) ) {
3555 if( !params.silent ) {
3556 sounds::sound( p, 18, sounds::sound_t::combat, _( "thump!" ),
3557 false, "smash_fail", "default" );
3558 }
3559
3560 result.did_bash = true;
3561 result.bashed_solid = true;
3562 }
3563
3564 return result;
3565 }
3566
3567 result.did_bash = true;
3568 result.bashed_solid = true;
3569 result.success = params.destroy;
3570
3571 int smin = bash->str_min;
3572 int smax = bash->str_max;
3573 if( !params.destroy ) {
3574 if( bash->str_min_blocked != -1 || bash->str_max_blocked != -1 ) {
3575 if( furn_is_supported( *this, p ) ) {
3576 if( bash->str_min_blocked != -1 ) {
3577 smin = bash->str_min_blocked;
3578 }
3579 if( bash->str_max_blocked != -1 ) {
3580 smax = bash->str_max_blocked;
3581 }
3582 }
3583 }
3584
3585 if( bash->str_min_supported != -1 || bash->str_max_supported != -1 ) {
3586 tripoint below( p.xy(), p.z - 1 );
3587 if( !zlevels || has_flag( TFLAG_SUPPORTS_ROOF, below ) ) {
3588 if( bash->str_min_supported != -1 ) {
3589 smin = bash->str_min_supported;
3590 }
3591 if( bash->str_max_supported != -1 ) {
3592 smax = bash->str_max_supported;
3593 }
3594 }
3595 }
3596 // Linear interpolation from str_min to str_max
3597 const int resistance = smin + ( params.roll * ( smax - smin ) );
3598 if( params.strength >= resistance ) {
3599 result.success = true;
3600 }
3601 }
3602
3603 if( !result.success ) {
3604 int sound_volume = bash->sound_fail_vol.value_or( 12 );
3605
3606 result.did_bash = true;
3607 if( !params.silent ) {
3608 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash->sound_fail, false,
3609 "smash_fail", soundfxvariant );
3610 }
3611 } else {
3612 if( smash_ter ) {
3613 result |= bash_ter_success( p, params );
3614 } else {
3615 result |= bash_furn_success( p, params );
3616 }
3617 }
3618
3619 return result;
3620}
ter_id get_roof(const tripoint &p, bool allow_air) const
Definition: map.cpp:3200
bash_results bash_furn_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3398
bash_results bash_ter_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3268
point ms_to_sm_copy(point p)
static bool furn_is_supported(const map &m, const tripoint &p)
Definition: map.cpp:3244
ter_id t_dirt
Definition: mapdata.cpp:627
@ TFLAG_SUPPORTS_ROOF
Definition: mapdata.h:280
float roll
Value from 0.0 to 1.0 that affects interpolation between str_min and str_max At 0....
Definition: map.h:147
bool bash_floor
Definition: map.h:140
bool destroy
Definition: map.h:138
int strength
Definition: map.h:134
@ TIMED_EVENT_WANTED
Definition: timed_event.h:13

References _, sounds::alarm, bash(), bash_params::bash_floor, bash_furn_success(), bash_ter_success(), sounds::combat, bash_params::destroy, furn(), furn_is_supported(), g, get_roof(), getabs(), has_flag(), impassable(), ms_to_sm_copy(), int_id< T >::obj(), rl_dist(), bash_params::roll, bash_params::silent, sounds::sound(), bash_params::strength, t_dirt, ter(), TFLAG_SUPPORTS_ROOF, TIMED_EVENT_WANTED, triggers_alarm, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash(), bash_ter_success(), and explosion_handler::ExplosionProcess::blast_tile().

◆ bash_ter_success()

bash_results map::bash_ter_success ( const tripoint p,
const bash_params params 
)

Definition at line 3268 of file map.cpp.

3269{
3271 result.success = true;
3272 const ter_t &ter_before = ter( p ).obj();
3273 const map_bash_info &bash = ter_before.bash;
3274 if( has_flag_ter( "FUNGUS", p ) ) {
3275 fungal_effects( *g, *this ).create_spores( p );
3276 }
3277 const std::string soundfxvariant = ter_before.id.str();
3278 const bool will_collapse = ter_before.has_flag( TFLAG_SUPPORTS_ROOF ) &&
3279 !ter_before.has_flag( TFLAG_INDOORS );
3280 const bool suspended = ter_before.has_flag( TFLAG_SUSPENDED );
3281 bool follow_below = false;
3282 if( params.bashing_from_above && bash.ter_set_bashed_from_above ) {
3283 // If this terrain is being bashed from above and this terrain
3284 // has a valid post-destroy bashed-from-above terrain, set it
3285 ter_set( p, bash.ter_set_bashed_from_above );
3286 } else if( bash.ter_set ) {
3287 // If the terrain has a valid post-destroy terrain, set it
3288 ter_set( p, bash.ter_set );
3289 follow_below |= zlevels && bash.bash_below;
3290 } else if( suspended ) {
3291 // Its important that we change the ter value before recursing, otherwise we'll hit an infinite loop.
3292 // This could be prevented by assembling a visited list, but in order to avoid that cost, we're going
3293 // build our recursion to just be resilient.
3294 ter_set( p, t_open_air );
3296 } else {
3297 tripoint below( p.xy(), p.z - 1 );
3298 const ter_t &ter_below = ter( below ).obj();
3299 // Only setting the flag here because we want drops and sounds in correct order
3300 follow_below |= zlevels && bash.bash_below && ter_below.roof;
3301
3302 ter_set( p, t_open_air );
3303 }
3304
3306
3307 if( !bash.sound.empty() && !params.silent ) {
3308 static const std::string soundfxid = "smash_success";
3309 int sound_volume = get_sound_volume( bash );
3310 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3311 soundfxid, soundfxvariant );
3312 }
3313
3314 if( !zlevels ) {
3315 if( ter( p ) == t_open_air ) {
3316 // We destroyed something, so we aren't just "plugging" air with dirt here
3317 ter_set( p, t_dirt );
3318 }
3319 } else if( follow_below || ter( p ) == t_open_air ) {
3320 const tripoint below( p.xy(), p.z - 1 );
3321 // We may need multiple bashes in some weird cases
3322 // Example:
3323 // W has roof A
3324 // A bashes to B
3325 // B bashes to nothing
3326 // Below our point P, there is a W
3327 // If we bash down a B over a W, it might be from earlier A or just constructed over it!
3328 //
3329 // Current solution: bash roof until you reach same roof type twice, then bash down
3330 if( follow_below && params.do_recurse ) {
3331 bool blocked_by_roof = false;
3332 std::set<ter_id> encountered_types;
3333 encountered_types.insert( ter_before.id );
3334 encountered_types.insert( t_open_air );
3335 // Note: we're bashing the new roof, not the tile supported by it!
3336 int down_bash_tries = 10;
3337 do {
3338 const ter_id &ter_now = ter( p );
3339 if( encountered_types.count( ter_now ) != 0 ) {
3340 // We have encountered this type before and destroyed it (didn't block us)
3341 ter_set( p, t_open_air );
3342 bash_params params_below = params;
3343 params_below.bashing_from_above = true;
3344 params_below.bash_floor = false;
3345 params_below.do_recurse = false;
3346 params_below.destroy = true;
3347 int impassable_bash_tries = 10;
3348 // Unconditionally destroy, but don't go deeper
3349 do {
3350 result |= bash_ter_success( below, params_below );
3351 } while( ter( below )->movecost == 0 && impassable_bash_tries-- > 0 );
3352 if( impassable_bash_tries <= 0 ) {
3353 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3354 }
3355 } else if( ter_now == t_open_air ) {
3356 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3357 if( roof != t_open_air ) {
3358 ter_set( p, roof );
3359 }
3360 } else {
3361 // This floor/roof tile wasn't destroyed in this loop yet
3362 encountered_types.insert( ter_now );
3363 bash_params params_copy = params;
3364 params_copy.do_recurse = false;
3365 // TODO: Unwrap the calls, don't recurse
3366 // TODO: Don't bash furn
3367 bash_results results_sub = bash_ter_furn( p, params_copy );
3368 result |= results_sub;
3369 if( !results_sub.success ) {
3370 // Blocked, as in "the roof was too strong to bash"
3371 blocked_by_roof = true;
3372 }
3373 }
3374 } while( down_bash_tries-- > 0 && !blocked_by_roof &&
3375 ( ter( p ) != t_open_air || ter( p )->movecost == 0 || ter( below )->roof ) );
3376 if( down_bash_tries <= 0 ) {
3377 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3378 }
3379 } else {
3380 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3381
3382 ter_set( p, roof );
3383 }
3384 }
3385
3386 if( will_collapse && !has_flag( TFLAG_SUPPORTS_ROOF, p ) ) {
3387 collapse_at( p, params.silent, true, bash.explosive > 0 );
3388 }
3389
3390 if( bash.explosive > 0 ) {
3391 // TODO Implement if the player triggered the explosive terrain
3392 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3393 }
3394
3395 return result;
3396}
void propagate_suspension_check(const tripoint &point)
Checks surrounding tiles for suspension, and has them check for collapse.
Definition: map.cpp:3004
void collapse_at(const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
Causes a collapse at p, such as from destroying a wall.
Definition: map.cpp:2959
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:255
@ TFLAG_SUSPENDED
Definition: mapdata.h:323
@ TFLAG_INDOORS
Definition: mapdata.h:291
bool do_recurse
Hack to prevent infinite recursion.
Definition: map.h:159
bool bashing_from_above
Definition: map.h:154
bool success
Definition: map.h:170
bool has_flag(const std::string &flag) const
Definition: mapdata.h:419
ter_str_id id
Definition: mapdata.h:465

References bash(), map_data_common_t::bash, bash_params::bash_floor, bash_ter_furn(), bash_ter_success(), bash_params::bashing_from_above, collapse_at(), sounds::combat, fungal_effects::create_spores(), debugmsg, bash_params::destroy, bash_params::do_recurse, explosion_handler::explosion(), g, get_roof(), get_sound_volume(), map_data_common_t::has_flag(), has_flag(), has_flag_ter(), ter_t::id, item_group::items_from(), int_id< T >::obj(), propagate_suspension_check(), ter_t::roof, bash_params::silent, sounds::sound(), spawn_items(), string_id< T >::str(), bash_results::success, t_dirt, t_open_air, ter(), ter_set(), TFLAG_INDOORS, TFLAG_SUPPORTS_ROOF, TFLAG_SUSPENDED, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash_ter_furn(), bash_ter_success(), and shoot().

◆ bash_vehicle()

bash_results map::bash_vehicle ( const tripoint p,
const bash_params params 
)

Definition at line 3694 of file map.cpp.

3695{
3697 // Smash vehicle if present
3698 if( const optional_vpart_position vp = veh_at( p ) ) {
3699 vp->vehicle().damage( vp->part_index(), params.strength, DT_BASH );
3700 if( !params.silent ) {
3701 sounds::sound( p, 18, sounds::sound_t::combat, _( "crash!" ), false,
3702 "smash_success", "hit_vehicle" );
3703 }
3704
3705 result.did_bash = true;
3706 result.success = true;
3707 result.bashed_solid = true;
3708 }
3709 return result;
3710}
@ DT_BASH
Definition: damage.h:24

References _, sounds::combat, DT_BASH, bash_params::silent, sounds::sound(), bash_params::strength, and veh_at().

Referenced by bash(), and explosion_handler::ExplosionProcess::blast_tile().

◆ batter()

void map::batter ( const tripoint p,
int  power,
int  tries = 1,
bool  silent = false 
)

bash a square for a set number of times at set power.

Does not destroy

Definition at line 3759 of file map.cpp.

3760{
3761 int count = 0;
3762 while( count < tries && bash( p, power, silent ).success ) {
3763 count++;
3764 }
3765}
@ success
Definition: behavior.h:20

References bash(), detail::count(), silent, and behavior::success.

Referenced by activity_handlers::chop_tree_finish().

◆ board_vehicle()

void map::board_vehicle ( const tripoint p,
player pl 
)

Definition at line 1113 of file map.cpp.

1114{
1115 if( p == nullptr ) {
1116 debugmsg( "map::board_vehicle: null player" );
1117 return;
1118 }
1119
1120 const std::optional<vpart_reference> vp = veh_at( pos ).part_with_feature( VPFLAG_BOARDABLE,
1121 true );
1122 if( !vp ) {
1123 if( p->grab_point.x == 0 && p->grab_point.y == 0 ) {
1124 debugmsg( "map::board_vehicle: vehicle not found" );
1125 }
1126 return;
1127 }
1128 if( vp->part().has_flag( vehicle_part::passenger_flag ) ) {
1129 player *psg = vp->vehicle().get_passenger( vp->part_index() );
1130 debugmsg( "map::board_vehicle: passenger (%s) is already there",
1131 psg ? psg->name : "<null>" );
1132 unboard_vehicle( pos );
1133 }
1134 vp->part().set_flag( vehicle_part::passenger_flag );
1135 vp->part().passenger_id = p->getID();
1136 vp->vehicle().invalidate_mass();
1137
1138 p->setpos( pos );
1139 p->in_vehicle = true;
1140 if( p->is_avatar() ) {
1141 g->update_map( g->u );
1142 }
1143}
std::string name
Definition: character.h:1539
void unboard_vehicle(const vpart_reference &, Character *passenger, bool dead_passenger=false)
Definition: map.cpp:1145
std::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2482
Definition: player.h:84
@ passenger_flag
Definition: vehicle.h:193
@ VPFLAG_BOARDABLE
Definition: veh_type.h:39

References debugmsg, g, Character::getID(), player::grab_point, Character::in_vehicle, Creature::is_avatar(), Character::name, optional_vpart_position::part_with_feature(), vehicle_part::passenger_flag, wrapped_vehicle::pos, Character::setpos(), unboard_vehicle(), veh_at(), VPFLAG_BOARDABLE, tripoint::x, and tripoint::y.

Referenced by debug_menu::debug(), npc::move_to(), game::phasing_move(), game::place_player(), game::swap_critters(), and avatar_action::swim().

◆ build_floor_cache()

bool map::build_floor_cache ( int  zlev)

Definition at line 8118 of file map.cpp.

8119{
8120 auto &ch = get_cache( zlev );
8121 if( !ch.floor_cache_dirty ) {
8122 return false;
8123 }
8124
8125 auto &floor_cache = ch.floor_cache;
8126 std::uninitialized_fill_n(
8127 &floor_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), true );
8128
8129 bool lowest_z_lev = zlev <= -OVERMAP_DEPTH;
8130 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8131 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8132 const submap *cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8133 const submap *below_submap = !lowest_z_lev ? get_submap_at_grid( { smx, smy, zlev - 1 } ) : nullptr;
8134
8135 if( cur_submap == nullptr ) {
8136 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy, zlev );
8137 continue;
8138 }
8139 if( !lowest_z_lev && below_submap == nullptr ) {
8140 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy,
8141 zlev - 1 );
8142 continue;
8143 }
8144
8145 for( int sx = 0; sx < SEEX; ++sx ) {
8146 for( int sy = 0; sy < SEEY; ++sy ) {
8147 point sp( sx, sy );
8148 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8149 if( terrain.has_flag( TFLAG_NO_FLOOR ) ) {
8150 if( below_submap && ( below_submap->get_furn( sp ).obj().has_flag( TFLAG_SUN_ROOF_ABOVE ) ) ) {
8151 continue;
8152 }
8153 const int x = sx + smx * SEEX;
8154 const int y = sy + smy * SEEY;
8155 floor_cache[x][y] = false;
8156 }
8157 }
8158 }
8159 }
8160 }
8161
8162 ch.floor_cache_dirty = false;
8163 return zlevels;
8164}
@ TFLAG_SUN_ROOF_ABOVE
Definition: mapdata.h:322
@ TFLAG_NO_FLOOR
Definition: mapdata.h:310
static const int sx[4]
Definition: tileray.cpp:10
static const int sy[4]
Definition: tileray.cpp:11

References debugmsg, get_cache(), get_submap_at_grid(), submap::get_ter(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, int_id< T >::obj(), OVERMAP_DEPTH, SEEX, SEEY, sx, sy, terrain, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, and zlevels.

Referenced by build_floor_caches(), and build_map_cache().

◆ build_floor_caches()

void map::build_floor_caches ( )

Definition at line 8166 of file map.cpp.

8167{
8168 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
8169 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
8170 for( int z = minz; z <= maxz; z++ ) {
8171 build_floor_cache( z );
8172 }
8173}
bool build_floor_cache(int zlev)
Definition: map.cpp:8118

References abs_sub, build_floor_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ build_map_cache()

void map::build_map_cache ( int  zlev,
bool  skip_lightmap = false 
)

Definition at line 8332 of file map.cpp.

8333{
8334 const int minz = zlevels ? -OVERMAP_DEPTH : zlev;
8335 const int maxz = zlevels ? OVERMAP_HEIGHT : zlev;
8336 bool seen_cache_dirty = false;
8337 for( int z = minz; z <= maxz; z++ ) {
8338 // trigger FOV recalculation only when there is a change on the player's level or if fov_3d is enabled
8339 const bool affects_seen_cache = z == zlev || fov_3d;
8343 seen_cache_dirty |= ( build_floor_cache( z ) && affects_seen_cache );
8344 seen_cache_dirty |= get_cache( z ).seen_cache_dirty && affects_seen_cache;
8345 diagonal_blocks fill = {false, false};
8346 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obscured_cache[0][0] ), MAPSIZE_X * MAPSIZE_Y,
8347 fill );
8348 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obstructed_cache[0][0] ),
8350 }
8351 // needs a separate pass as it changes the caches on neighbour z-levels (e.g. floor_cache);
8352 // otherwise such changes might be overwritten by main cache-building logic
8353 for( int z = minz; z <= maxz; z++ ) {
8354 do_vehicle_caching( z );
8355 }
8356
8358
8359 if( seen_cache_dirty ) {
8360 skew_vision_cache.clear();
8361 }
8362 // Initial value is illegal player position.
8363 const tripoint &p = g->u.pos();
8364 static tripoint player_prev_pos;
8365 if( seen_cache_dirty || player_prev_pos != p ) {
8366 build_seen_cache( p, zlev );
8367 player_prev_pos = p;
8368 }
8369 if( !skip_lightmap ) {
8370 generate_lightmap( zlev );
8371 }
8372}
bool fov_3d
3D FoV enabled/disabled.
void build_outside_cache(int zlev)
Definition: map.cpp:8011
void update_suspension_cache(const int &z)
Definition: map.cpp:8175
void do_vehicle_caching(int z)
Definition: map.cpp:8315
void build_seen_cache(const tripoint &origin, int target_z)
Calculates the Field Of View for the provided map from the given x, y coordinates.
Definition: lightmap.cpp:1591
lru_cache< point, char > skew_vision_cache
Cache of coordinate pairs recently checked for visibility.
Definition: map.h:1979
bool build_transparency_cache(int zlev)
Definition: lightmap.cpp:104
void generate_lightmap(int zlev)
Definition: lightmap.cpp:435
bool build_vision_transparency_cache(const Character &player)
Definition: lightmap.cpp:203
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
bool seen_cache_dirty
Definition: map.h:309

References build_floor_cache(), build_outside_cache(), build_seen_cache(), build_transparency_cache(), build_vision_transparency_cache(), do_vehicle_caching(), detail::fill(), fov_3d, g, generate_lightmap(), get_cache(), get_player_character(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::seen_cache_dirty, skew_vision_cache, update_suspension_cache(), and zlevels.

Referenced by game::do_turn(), game::draw(), game::look_around(), start_location::place_player(), game::start_game(), and game::update_map().

◆ build_obstacle_cache()

void map::build_obstacle_cache ( const tripoint start,
const tripoint end,
float(&)  obstacle_cache[MAPSIZE_X][MAPSIZE_Y] 
)

Definition at line 8065 of file map.cpp.

8067{
8068 const point min_submap{ std::max( 0, start.x / SEEX ), std::max( 0, start.y / SEEY ) };
8069 const point max_submap{
8070 std::min( my_MAPSIZE - 1, end.x / SEEX ), std::min( my_MAPSIZE - 1, end.y / SEEY ) };
8071 // Find and cache all the map obstacles.
8072 // For now setting obstacles to be extremely dense and fill their squares.
8073 // In future, scale effective obstacle density by the thickness of the obstacle.
8074 // Also consider modelling partial obstacles.
8075 // TODO: Support z-levels.
8076 for( int smx = min_submap.x; smx <= max_submap.x; ++smx ) {
8077 for( int smy = min_submap.y; smy <= max_submap.y; ++smy ) {
8078 const auto cur_submap = get_submap_at_grid( { smx, smy, start.z } );
8079
8080 // TODO: Init indices to prevent iterating over unused submap sections.
8081 for( int sx = 0; sx < SEEX; ++sx ) {
8082 for( int sy = 0; sy < SEEY; ++sy ) {
8083 const point sp( sx, sy );
8084 int ter_move = cur_submap->get_ter( sp ).obj().movecost;
8085 int furn_move = cur_submap->get_furn( sp ).obj().movecost;
8086 const int x = sx + smx * SEEX;
8087 const int y = sy + smy * SEEY;
8088 if( ter_move == 0 || furn_move < 0 || ter_move + furn_move == 0 ) {
8089 obstacle_cache[x][y] = 1000.0f;
8090 } else {
8091 obstacle_cache[x][y] = 0.0f;
8092 }
8093 }
8094 }
8095 }
8096 }
8097 VehicleList vehs = get_vehicles( start, end );
8098 const inclusive_cuboid<tripoint> bounds( start, end );
8099 // Cache all the vehicle stuff in one loop
8100 for( auto &v : vehs ) {
8101 for( const vpart_reference &vp : v.v->get_all_parts() ) {
8102 tripoint p = v.pos + vp.part().precalc[0];
8103 if( p.z != start.z ) {
8104 break;
8105 }
8106 if( !bounds.contains( p ) ) {
8107 continue;
8108 }
8109
8110 if( vp.obstacle_at_part() ) {
8111 obstacle_cache[p.x][p.y] = 1000.0f;
8112 }
8113 }
8114 }
8115
8116}
VehicleList get_vehicles()
Definition: map.cpp:296
std::vector< wrapped_vehicle > VehicleList
Definition: map.h:85

References inclusive_cuboid< Tripoint, >::contains(), get_submap_at_grid(), get_vehicles(), my_MAPSIZE, SEEX, SEEY, sx, sy, tripoint::x, tripoint::y, and tripoint::z.

Referenced by explosion_handler::legacy_shrapnel().

◆ build_outside_cache()

void map::build_outside_cache ( int  zlev)

Definition at line 8011 of file map.cpp.

8012{
8013 auto &ch = get_cache( zlev );
8014 if( !ch.outside_cache_dirty ) {
8015 return;
8016 }
8017
8018 // Make a bigger cache to avoid bounds checking
8019 // We will later copy it to our regular cache
8020 const size_t padded_w = ( MAPSIZE_X ) + 2;
8021 const size_t padded_h = ( MAPSIZE_Y ) + 2;
8022 bool padded_cache[padded_w][padded_h];
8023
8024 auto &outside_cache = ch.outside_cache;
8025 if( zlev < 0 ) {
8026 std::uninitialized_fill_n(
8027 &outside_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), false );
8028 return;
8029 }
8030
8031 std::uninitialized_fill_n(
8032 &padded_cache[0][0], padded_w * padded_h, true );
8033
8034 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8035 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8036 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8037
8038 for( int sx = 0; sx < SEEX; ++sx ) {
8039 for( int sy = 0; sy < SEEY; ++sy ) {
8040 point sp( sx, sy );
8041 if( cur_submap->get_ter( sp ).obj().has_flag( TFLAG_INDOORS ) ||
8042 cur_submap->get_furn( sp ).obj().has_flag( TFLAG_INDOORS ) ) {
8043 const int x = sx + smx * SEEX;
8044 const int y = sy + smy * SEEY;
8045 // Add 1 to both coordinates, because we're operating on the padded cache
8046 for( int dx = 0; dx <= 2; dx++ ) {
8047 for( int dy = 0; dy <= 2; dy++ ) {
8048 padded_cache[x + dx][y + dy] = false;
8049 }
8050 }
8051 }
8052 }
8053 }
8054 }
8055 }
8056
8057 // Copy the padded cache back to the proper one, but with no padding
8058 for( int x = 0; x < SEEX * my_MAPSIZE; x++ ) {
8059 std::copy_n( &padded_cache[x + 1][1], SEEX * my_MAPSIZE, &outside_cache[x][0] );
8060 }
8061
8062 ch.outside_cache_dirty = false;
8063}

References get_cache(), get_submap_at_grid(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, sx, sy, and TFLAG_INDOORS.

Referenced by build_map_cache(), start_location::burn(), and start_location::prepare_map().

◆ build_seen_cache()

void map::build_seen_cache ( const tripoint origin,
int  target_z 
)
protected

Calculates the Field Of View for the provided map from the given x, y coordinates.

Returns a lightmap for a result where the values represent a percentage of fully lit.

A value equal to or below 0 means that cell is not in the field of view, whereas a value equal to or above 1 means that cell is in the field of view.

Parameters
originthe starting location
target_zZ-level to draw light map on

Definition at line 1591 of file lightmap.cpp.

1592{
1593 auto &map_cache = get_cache( target_z );
1594 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1595 float ( &seen_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.seen_cache;
1596 float ( &camera_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.camera_cache;
1597 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1598
1599 constexpr float light_transparency_solid = LIGHT_TRANSPARENCY_SOLID;
1600 constexpr int map_dimensions = MAPSIZE_X * MAPSIZE_Y;
1601 std::uninitialized_fill_n(
1602 &camera_cache[0][0], map_dimensions, light_transparency_solid );
1603
1604 float vision_restore_cache [9] = {0};
1605 bool blocked_restore_cache[8] = {false};
1606
1607 if( origin.z == target_z ) {
1608 apply_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1609 blocked_restore_cache );
1610 }
1611
1612 if( !fov_3d ) {
1613 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1614 auto &cur_cache = get_cache( z );
1615 if( z == target_z || cur_cache.seen_cache_dirty ) {
1616 std::uninitialized_fill_n(
1617 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1618 cur_cache.seen_cache_dirty = false;
1619 }
1620
1621 if( z == target_z ) {
1622 seen_cache[origin.x][origin.y] = VISIBILITY_FULL;
1624 ( seen_cache, transparency_cache, blocked_cache, origin.xy(), 0 );
1625 }
1626 }
1627 } else {
1628 // Cache the caches (pointers to them)
1629 array_of_grids_of<const float> transparency_caches;
1630 array_of_grids_of<float> seen_caches;
1631 array_of_grids_of<const bool> floor_caches;
1633 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1634 auto &cur_cache = get_cache( z );
1635 transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.transparency_cache;
1636 seen_caches[z + OVERMAP_DEPTH] = &cur_cache.seen_cache;
1637 floor_caches[z + OVERMAP_DEPTH] = &cur_cache.floor_cache;
1638 blocked_caches[z + OVERMAP_DEPTH] = &cur_cache.vehicle_obscured_cache;
1639 std::uninitialized_fill_n(
1640 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1641 cur_cache.seen_cache_dirty = false;
1642 }
1643 if( origin.z == target_z ) {
1645 }
1647 seen_caches, transparency_caches, floor_caches, blocked_caches, origin, 0, 1.0 );
1648 }
1649
1650 if( origin.z == target_z ) {
1651 restore_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1652 blocked_restore_cache );
1653 }
1654
1656 if( !vp ) {
1657 return;
1658 }
1659 vehicle *const veh = &vp->vehicle();
1660
1661 // We're inside a vehicle. Do mirror calculations.
1662 std::vector<int> mirrors;
1663 // Do all the sight checks first to prevent fake multiple reflection
1664 // from happening due to mirrors becoming visible due to processing order.
1665 // Cameras are also handled here, so that we only need to get through all vehicle parts once
1666 int cam_control = -1;
1667 for( const vpart_reference &vp : veh->get_avail_parts( VPFLAG_EXTENDS_VISION ) ) {
1668 const tripoint mirror_pos = vp.pos();
1669 // We can utilize the current state of the seen cache to determine
1670 // if the player can see the mirror from their position.
1671 if( !vp.info().has_flag( "CAMERA" ) &&
1672 seen_cache[mirror_pos.x][mirror_pos.y] < LIGHT_TRANSPARENCY_SOLID + 0.1 ) {
1673 continue;
1674 } else if( !vp.info().has_flag( "CAMERA_CONTROL" ) ) {
1675 mirrors.emplace_back( static_cast<int>( vp.part_index() ) );
1676 } else {
1677 if( square_dist( origin, mirror_pos ) <= 1 && veh->camera_on ) {
1678 cam_control = static_cast<int>( vp.part_index() );
1679 }
1680 }
1681 }
1682
1683 for( int mirror : mirrors ) {
1684 bool is_camera = veh->part_info( mirror ).has_flag( "CAMERA" );
1685 if( is_camera && cam_control < 0 ) {
1686 continue; // Player not at camera control, so cameras don't work
1687 }
1688
1689 const tripoint mirror_pos = veh->global_part_pos3( mirror );
1690
1691 // Determine how far the light has already traveled so mirrors
1692 // don't cheat the light distance falloff.
1693 int offsetDistance;
1694 if( !is_camera ) {
1695 offsetDistance = rl_dist( origin, mirror_pos );
1696 } else {
1697 offsetDistance = 60 - veh->part_info( mirror ).bonus *
1698 veh->part( mirror ).hp() / veh->part_info( mirror ).durability;
1699 camera_cache[mirror_pos.x][mirror_pos.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
1700 }
1701
1702 // TODO: Factor in the mirror facing and only cast in the
1703 // directions the player's line of sight reflects to.
1704 //
1705 // The naive solution of making the mirrors act like a second player
1706 // at an offset appears to give reasonable results though.
1708 (
1709 camera_cache, transparency_cache, blocked_cache, mirror_pos.xy(), offsetDistance );
1710 }
1711}
void restore_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1505
void apply_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1466
vehicle_part_with_feature_range< std::string > get_avail_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are available: not broke...
Definition: vehicle.cpp:2715
bool camera_on
Definition: vehicle.h:2021
const vpart_info & part_info(int index, bool include_removed=false) const
Definition: vehicle.cpp:1138
int bonus
seatbelt (str), muffler (%), horn (vol), light (intensity), recharing (power)
Definition: veh_type.h:269
bool has_flag(const std::string &flag) const
Definition: veh_type.h:336
int durability
Maximum damage part can sustain before being destroyed.
Definition: veh_type.h:173
template void cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(const array_of_grids_of< float > &output_caches, const array_of_grids_of< const float > &input_arrays, const array_of_grids_of< const bool > &floor_caches, const array_of_grids_of< const diagonal_blocks > &blocked_caches, const tripoint &origin, int offset_distance, float numerator)
template void castLightAllWithLookup< float, float, sight_calc, sight_check, update_light, accumulate_transparency, sight_from_lookup >(float(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const float(&input_array)[MAPSIZE_X][MAPSIZE_Y], const diagonal_blocks(&blocked_array)[MAPSIZE_X][MAPSIZE_Y], const point &offset, int offsetDistance, float numerator)
static constexpr float VISIBILITY_FULL
Definition: lightmap.h:39
std::array< T(*)[MAPSIZE_X][MAPSIZE_Y], OVERMAP_LAYERS > array_of_grids_of
int hp() const
current part health with range [0,durability]
@ VPFLAG_EXTENDS_VISION
Definition: veh_type.h:68

References apply_vision_transparency_cache(), vpart_info::bonus, vehicle::camera_on, cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(), castLightAllWithLookup< float, float, sight_calc, sight_check, update_light, accumulate_transparency, sight_from_lookup >(), vpart_info::durability, fov_3d, vehicle::get_avail_parts(), get_cache(), get_player_character(), vehicle::global_part_pos3(), vpart_info::has_flag(), vehicle_part::hp(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::part(), vehicle::part_info(), restore_vision_transparency_cache(), rl_dist(), level_cache::seen_cache, square_dist(), veh_at(), VISIBILITY_FULL, VPFLAG_EXTENDS_VISION, tripoint::x, tripoint::xy(), and tripoint::y.

Referenced by build_map_cache().

◆ build_sunlight_cache()

void map::build_sunlight_cache ( int  pzlev)
protected

Definition at line 284 of file lightmap.cpp.

285{
286 const int zlev_min = zlevels ? -OVERMAP_DEPTH : pzlev;
287 // Start at the topmost populated zlevel to avoid unnecessary raycasting
288 // Plus one zlevel to prevent clipping inside structures
289 const int zlev_max = zlevels
291 std::min( OVERMAP_HEIGHT, pzlev + 1 ),
293 : pzlev;
294
295 // true if all previous z-levels are fully transparent to light (no floors, transparency >= air)
296 bool fully_outside = true;
297
298 // true if no light reaches this level, i.e. there were no lit tiles on the above level (light level <= inside_light_level)
299 bool fully_inside = false;
300
301 // fully_outside and fully_inside define following states:
302 // initially: fully_outside=true, fully_inside=false (fast fill)
303 // ↓
304 // when first obstacles occur: fully_outside=false, fully_inside=false (slow quadrant logic)
305 // ↓
306 // when fully below ground: fully_outside=false, fully_inside=true (fast fill)
307
308 // Iterate top to bottom because sunlight cache needs to construct in that order.
309 for( int zlev = zlev_max; zlev >= zlev_min; zlev-- ) {
310
311 level_cache &map_cache = get_cache( zlev );
312 auto &lm = map_cache.lm;
313 // Grab illumination at ground level.
314 const float outside_light_level = g->natural_light_level( 0 );
315 // TODO: if zlev < 0 is open to sunlight, this won't calculate correct light, but neither does g->natural_light_level()
316 const float inside_light_level = ( zlev >= 0 && outside_light_level > LIGHT_SOURCE_BRIGHT ) ?
318 // Handling when z-levels are disabled is based on whether a tile is considered "outside".
319 if( !zlevels ) {
320 const auto &outside_cache = map_cache.outside_cache;
321 for( int x = 0; x < MAPSIZE_X; x++ ) {
322 for( int y = 0; y < MAPSIZE_Y; y++ ) {
323 if( outside_cache[x][y] ) {
324 lm[x][y].fill( outside_light_level );
325 } else {
326 lm[x][y].fill( inside_light_level );
327 }
328 }
329 }
330 continue;
331 }
332
333 // all light was blocked before
334 if( fully_inside ) {
335 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
336 continue;
337 }
338
339 // If there were no obstacles before this level, just apply weather illumination since there's no opportunity
340 // for light to be blocked.
341 if( fully_outside ) {
342 //fill with full light
343 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( outside_light_level ) );
344
345 const auto &this_floor_cache = map_cache.floor_cache;
346 const auto &this_transparency_cache = map_cache.transparency_cache;
347 fully_inside = true; // recalculate
348
349 for( int x = 0; x < MAPSIZE_X; ++x ) {
350 for( int y = 0; y < MAPSIZE_Y; ++y ) {
351 // && semantics below is important, we want to skip the evaluation if possible, do not replace with &=
352
353 // fully_outside stays true if tile is transparent and there is no floor
354 fully_outside = fully_outside && this_transparency_cache[x][y] >= LIGHT_TRANSPARENCY_OPEN_AIR
355 && !this_floor_cache[x][y];
356 // fully_inside stays true if tile is opaque OR there is floor
357 fully_inside = fully_inside && ( this_transparency_cache[x][y] <= LIGHT_TRANSPARENCY_SOLID ||
358 this_floor_cache[x][y] );
359 }
360 }
361 continue;
362 }
363
364 // Replace this with a calculated shift based on time of day and date.
365 // At first compress the angle such that it takes no more than one tile of shift per level.
366 // To exceed that, we'll have to handle casting light from the side instead of the top.
367 point offset;
368 const level_cache &prev_map_cache = get_cache_ref( zlev + 1 );
369 const auto &prev_lm = prev_map_cache.lm;
370 const auto &prev_transparency_cache = prev_map_cache.transparency_cache;
371 const auto &prev_floor_cache = prev_map_cache.floor_cache;
372 const auto &outside_cache = map_cache.outside_cache;
373 const float sight_penalty = get_weather().weather_id->sight_penalty;
374 // TODO: Replace these with a lookup inside the four_quadrants class.
375 constexpr std::array<point, 5> cardinals = {
377 };
378 constexpr std::array<std::array<quadrant, 2>, 5> dir_quadrants = {{
384 }
385 };
386
387 fully_inside = true; // recalculate
388
389 // Fall back to minimal light level if we don't find anything.
390 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
391
392 for( int x = 0; x < MAPSIZE_X; ++x ) {
393 for( int y = 0; y < MAPSIZE_Y; ++y ) {
394 // Check center, then four adjacent cardinals.
395 for( int i = 0; i < 5; ++i ) {
396 int prev_x = x + offset.x + cardinals[i].x;
397 int prev_y = y + offset.y + cardinals[i].y;
398 bool inbounds = prev_x >= 0 && prev_x < MAPSIZE_X &&
399 prev_y >= 0 && prev_y < MAPSIZE_Y;
400
401 if( !inbounds ) {
402 continue;
403 }
404
405 float prev_light_max;
406 float prev_transparency = prev_transparency_cache[prev_x][prev_y];
407 // This is pretty gross, this cancels out the per-tile transparency effect
408 // derived from weather.
409 if( outside_cache[x][y] ) {
410 prev_transparency /= sight_penalty;
411 }
412
413 if( prev_transparency > LIGHT_TRANSPARENCY_SOLID &&
414 !prev_floor_cache[prev_x][prev_y] &&
415 ( prev_light_max = prev_lm[prev_x][prev_y].max() ) > 0.0 ) {
416 const float light_level = clamp( prev_light_max * LIGHT_TRANSPARENCY_OPEN_AIR / prev_transparency,
417 inside_light_level, prev_light_max );
418
419 if( i == 0 ) {
420 lm[x][y].fill( light_level );
421 fully_inside &= light_level <= inside_light_level;
422 break;
423 } else {
424 fully_inside &= light_level <= inside_light_level;
425 lm[x][y][dir_quadrants[i][0]] = light_level;
426 lm[x][y][dir_quadrants[i][1]] = light_level;
427 }
428 }
429 }
430 }
431 }
432 }
433}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:149
int calc_max_populated_zlev()
Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.
Definition: map.cpp:9115
weather_type_id weather_id
Definition: weather.h:193
weather_manager & get_weather()
Definition: weather.cpp:64
static constexpr float LIGHT_AMBIENT_DIM
Definition: lightmap.h:16
bool floor_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:328
bool outside_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:322
float sight_penalty
Definition: weather_type.h:111

References calc_max_populated_zlev(), clamp(), level_cache::floor_cache, g, get_cache(), get_cache_ref(), get_weather(), inbounds(), LIGHT_AMBIENT_DIM, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, level_cache::lm, MAPSIZE_X, MAPSIZE_Y, NE, NW, level_cache::outside_cache, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_east, point_north, point_south, point_west, point_zero, SE, weather_type::sight_penalty, SW, level_cache::transparency_cache, weather_manager::weather_id, point::x, point::y, and zlevels.

Referenced by generate_lightmap().

◆ build_transparency_cache()

bool map::build_transparency_cache ( int  zlev)
protected

Definition at line 104 of file lightmap.cpp.

105{
106 auto &map_cache = get_cache( zlev );
107 auto &transparency_cache = map_cache.transparency_cache;
108 auto &outside_cache = map_cache.outside_cache;
109
110 if( map_cache.transparency_cache_dirty.none() ) {
111 return false;
112 }
113
114 std::set<tripoint> vehicles_processed;
115
116 // if true, all submaps are invalid (can use batch init)
117 bool rebuild_all = map_cache.transparency_cache_dirty.all();
118
119 if( rebuild_all ) {
120 // Default to just barely not transparent.
121 std::uninitialized_fill_n( &transparency_cache[0][0], MAPSIZE_X * MAPSIZE_Y,
122 static_cast<float>( LIGHT_TRANSPARENCY_OPEN_AIR ) );
123 }
124
125 const float sight_penalty = get_weather().weather_id->sight_penalty;
126
127 if( sight_penalty != 1.0f &&
128 LIGHT_TRANSPARENCY_OPEN_AIR * sight_penalty != weather_transparency_lookup.transparency ) {
130 }
131
132 // Traverse the submaps in order
133 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
134 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
135 const auto cur_submap = get_submap_at_grid( {smx, smy, zlev} );
136
137 const point sm_offset = sm_to_ms_copy( point( smx, smy ) );
138
139 if( !rebuild_all && !map_cache.transparency_cache_dirty[smx * MAPSIZE + smy] ) {
140 continue;
141 }
142
143 // calculates transparency of a single tile
144 // x,y - coords in map local coords
145 auto calc_transp = [&]( point p ) {
146 const point sp = p - sm_offset;
147 float value = LIGHT_TRANSPARENCY_OPEN_AIR;
148
149 if( !( cur_submap->get_ter( sp ).obj().transparent &&
150 cur_submap->get_furn( sp ).obj().transparent ) ) {
152 }
153 if( outside_cache[p.x][p.y] ) {
154 // FIXME: Places inside vehicles haven't been marked as
155 // inside yet so this is incorrectly penalising for
156 // weather in vehicles.
157 value *= sight_penalty;
158 }
159 for( const auto &fld : cur_submap->get_field( sp ) ) {
160 const field_entry &cur = fld.second;
161 if( cur.is_transparent() ) {
162 continue;
163 }
164 // Fields are either transparent or not, however we want some to be translucent
165 value = value * cur.translucency();
166 }
167 // TODO: [lightmap] Have glass reduce light as well
168 return value;
169 };
170
171 if( cur_submap->is_uniform ) {
172 float value = calc_transp( sm_offset );
173 // if rebuild_all==true all values were already set to LIGHT_TRANSPARENCY_OPEN_AIR
174 if( !rebuild_all || value != LIGHT_TRANSPARENCY_OPEN_AIR ) {
175 for( int sx = 0; sx < SEEX; ++sx ) {
176 // init all sy indices in one go
177 std::uninitialized_fill_n( &transparency_cache[sm_offset.x + sx][sm_offset.y], SEEY, value );
178 }
179 }
180 } else {
181 for( int sx = 0; sx < SEEX; ++sx ) {
182 const int x = sx + sm_offset.x;
183 for( int sy = 0; sy < SEEY; ++sy ) {
184 const int y = sy + sm_offset.y;
185 transparency_cache[x][y] = calc_transp( { x, y } );
186
187 //Nudge things towards fast paths
188 if( std::fabs( transparency_cache[x][y] - openair_transparency_lookup.transparency ) <= 0.0001 ) {
189 transparency_cache[x][y] = openair_transparency_lookup.transparency;
190 } else if( std::fabs( transparency_cache[x][y] - weather_transparency_lookup.transparency ) <=
191 0.0001 ) {
192 transparency_cache[x][y] = weather_transparency_lookup.transparency;
193 }
194 }
195 }
196 }
197 }
198 }
199 map_cache.transparency_cache_dirty.reset();
200 return true;
201}
An active or passive effect existing on a tile.
Definition: field.h:20
bool is_transparent() const
Definition: field.cpp:84
float translucency() const
Definition: field.cpp:79
transparency_exp_lookup< 90 > weather_transparency_lookup(LIGHT_TRANSPARENCY_OPEN_AIR *1.1)
const transparency_exp_lookup< 90 > openair_transparency_lookup(LIGHT_TRANSPARENCY_OPEN_AIR)
quantity< V, U > fabs(quantity< V, U > q)
Definition: units_def.h:136

References units::fabs(), get_cache(), get_submap_at_grid(), get_weather(), field_entry::is_transparent(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, openair_transparency_lookup, SEEX, SEEY, weather_type::sight_penalty, sm_to_ms_copy(), sx, sy, field_entry::translucency(), weather_manager::weather_id, and weather_transparency_lookup.

Referenced by build_map_cache().

◆ build_vision_transparency_cache()

bool map::build_vision_transparency_cache ( const Character player)
protected

Definition at line 203 of file lightmap.cpp.

204{
205 const tripoint &p = player.pos();
206
207 bool dirty = false;
208
210
211 const auto check_vehicle_coverage = []( const vehicle * veh, point p ) -> bool {
212 return veh->obstacle_at_position( p ) == -1 && ( veh->part_with_feature( p, "AISLE", true ) != -1 || veh->part_with_feature( p, "PROTRUSION", true ) != -1 );
213 };
214
215 const optional_vpart_position player_vp = veh_at( p );
216
217 point player_mount;
218 if( player_vp ) {
219 player_mount = player_vp->vehicle().tripoint_to_mount( p );
220 }
221
222 int i = 0;
223 for( point adjacent : eight_adjacent_offsets ) {
225
226 // If we're crouching behind an obstacle, we can't see past it.
227 if( coverage( adjacent + p ) >= 30 ) {
228 dirty = true;
230 } else {
232 adjacent ) != four_diagonal_offsets.end() ) {
233 const optional_vpart_position adjacent_vp = veh_at( p + adjacent );
234
235 point adjacent_mount;
236 if( adjacent_vp ) {
237 adjacent_mount = adjacent_vp->vehicle().tripoint_to_mount( p );
238 }
239
240 if( ( player_vp &&
241 !player_vp->vehicle().check_rotated_intervening( player_mount,
242 player_vp->vehicle().tripoint_to_mount( p + adjacent ),
243 check_vehicle_coverage ) )
244 || ( adjacent_vp && ( !player_vp || &( player_vp->vehicle() ) != &( adjacent_vp->vehicle() ) ) &&
245 !adjacent_vp->vehicle().check_rotated_intervening( adjacent_vp->vehicle().tripoint_to_mount(
246 p ), adjacent_vp->vehicle().tripoint_to_mount( p + adjacent ),
247 check_vehicle_coverage ) ) ) {
248 dirty = true;
250 }
251 }
252 }
253
254 i++;
255 }
256 } else {
257 std::fill_n( &vision_transparency_cache[0], 8, VISION_ADJUST_NONE );
258 }
259 return dirty;
260}
@ CMM_CROUCH
Definition: character.h:111
bool movement_mode_is(character_movemode mode) const
Check against the character's current movement mode.
Definition: character.cpp:1545
int coverage(const tripoint &p) const
Returns coverage value of the tile.
Definition: map.cpp:6354
int part_with_feature(int p, const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2521
int obstacle_at_position(point pos) const
Definition: vehicle.cpp:2583
@ VISION_ADJUST_NONE
Definition: lightmap.h:77

References CMM_CROUCH, coverage(), eight_adjacent_offsets, detail::find(), four_diagonal_offsets, Character::movement_mode_is(), vehicle::obstacle_at_position(), vehicle::part_with_feature(), Character::pos(), veh_at(), VISION_ADJUST_HIDDEN, VISION_ADJUST_NONE, VISION_ADJUST_SOLID, and vision_transparency_cache.

Referenced by build_map_cache().

◆ burn_body_part()

int map::burn_body_part ( player u,
field_entry cur,
body_part  bp,
int  scale 
)
private

Definition at line 124 of file map_field.cpp.

125{
126 int total_damage = 0;
127 const int intensity = cur.get_field_intensity();
128 const int damage = rng( 1, ( scale + intensity ) / 2 );
129 // A bit ugly, but better than being annoyed by acid when in hazmat
130 if( u.get_armor_type( DT_ACID, convert_bp( bp ) ) < damage ) {
131 const dealt_damage_instance ddi = u.deal_damage( nullptr, convert_bp( bp ).id(),
132 damage_instance( DT_ACID, damage ) );
133 total_damage += ddi.total_damage();
134 }
135 // Represents acid seeping in rather than being splashed on
137 1 + intensity ) ), bp, 0 );
138 return total_damage;
139}
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8437
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6859
bool add_env_effect(const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
Gives chance to save via environmental resist, returns false if resistance was successful.
Definition: creature.cpp:1119
int get_field_intensity() const
Definition: field.cpp:121
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_corroding("corroding")
int total_damage() const
Definition: damage.cpp:180

References Creature::add_env_effect(), convert_bp(), Character::deal_damage(), DT_ACID, effect_corroding, time_duration::from_turns(), Character::get_armor_type(), field_entry::get_field_intensity(), rng(), and dealt_damage_instance::total_damage().

Referenced by player_in_field().

◆ calc_max_populated_zlev()

int map::calc_max_populated_zlev ( )
private

Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.

fills the map::max_populated_zlev and returns it

Returns
max_populated_zlev value

Definition at line 9115 of file map.cpp.

9116{
9117 // cache is filled and valid, skip recalculation
9119 return max_populated_zlev->second;
9120 }
9121
9122 // We'll assume ground level is populated
9123 int max_z = 0;
9124
9125 for( int sz = 1; sz <= OVERMAP_HEIGHT; sz++ ) {
9126 bool level_done = false;
9127 for( int sx = 0; sx < my_MAPSIZE; sx++ ) {
9128 for( int sy = 0; sy < my_MAPSIZE; sy++ ) {
9129 const submap *sm = get_submap_at_grid( tripoint( sx, sy, sz ) );
9130 if( !sm->is_uniform ) {
9131 max_z = sz;
9132 level_done = true;
9133 break;
9134 }
9135 }
9136 if( level_done ) {
9137 break;
9138 }
9139 }
9140 }
9141
9142 max_populated_zlev = std::pair<tripoint, int>( get_abs_sub(), max_z );
9143 return max_z;
9144}
std::optional< std::pair< tripoint, int > > max_populated_zlev
Definition: map.h:1998
tripoint get_abs_sub() const
return abs_sub
Definition: map.cpp:8403

References get_abs_sub(), get_submap_at_grid(), max_populated_zlev, my_MAPSIZE, OVERMAP_HEIGHT, coords::sm, sx, and sy.

Referenced by build_sunlight_cache().

◆ can_move_furniture()

bool map::can_move_furniture ( const tripoint pos,
player p = nullptr 
)
Strength determines what furniture the player can move

Definition at line 1509 of file map.cpp.

1510{
1511 if( !p ) {
1512 return false;
1513 }
1514 const furn_t &furniture_type = furn( pos ).obj();
1515 int required_str = furniture_type.move_str_req;
1516
1517 // Object can not be moved (or nothing there)
1518 if( required_str < 0 ) {
1519 return false;
1520 }
1521
1522 ///\EFFECT_STR determines what furniture the player can move
1523 int adjusted_str = p->str_cur;
1524 if( p->is_mounted() ) {
1525 auto mons = p->mounted_creature.get();
1526 if( mons->has_flag( MF_RIDEABLE_MECH ) && mons->mech_str_addition() != 0 ) {
1527 adjusted_str = mons->mech_str_addition();
1528 }
1529 }
1530 return adjusted_str >= required_str;
1531}
int str_cur
Definition: character.h:264
bool is_mounted() const
Definition: character.cpp:1069
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1591
@ MF_RIDEABLE_MECH
Definition: mtype.h:115
int move_str_req
Definition: mapdata.h:515

References furn(), Character::is_mounted(), MF_RIDEABLE_MECH, Character::mounted_creature, furn_t::move_str_req, int_id< T >::obj(), wrapped_vehicle::pos, and Character::str_cur.

Referenced by grab().

◆ can_put_items() [1/2]

bool map::can_put_items ( const tripoint p) const

Definition at line 2379 of file map.cpp.

2380{
2381 if( can_put_items_ter_furn( p ) ) {
2382 return true;
2383 }
2384 const optional_vpart_position vp = veh_at( p );
2385 return static_cast<bool>( vp.part_with_feature( "CARGO", true ) );
2386}
bool can_put_items_ter_furn(const tripoint &p) const
Definition: map.cpp:2388

References can_put_items_ter_furn(), optional_vpart_position::part_with_feature(), and veh_at().

Referenced by can_put_items(), complete_construction(), haul(), and game::place_player().

◆ can_put_items() [2/2]

bool map::can_put_items ( point  p) const
inline

Definition at line 909 of file map.h.

909 {
910 return can_put_items( tripoint( p, abs_sub.z ) );
911 }
bool can_put_items(const tripoint &p) const
Definition: map.cpp:2379

References abs_sub, can_put_items(), and tripoint::z.

◆ can_put_items_ter_furn() [1/2]

bool map::can_put_items_ter_furn ( const tripoint p) const

◆ can_put_items_ter_furn() [2/2]

bool map::can_put_items_ter_furn ( point  p) const
inline

Definition at line 914 of file map.h.

914 {
916 }

References abs_sub, can_put_items_ter_furn(), and tripoint::z.

◆ can_see_trap_at()

bool map::can_see_trap_at ( const tripoint p,
const Character c 
) const

See trap::can_see, which is called for the trap here.

Definition at line 5230 of file map.cpp.

5231{
5232 return tr_at( p ).can_see( p, c );
5233}
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5235
constexpr double c
Definition: magic.cpp:1032
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References c, trap::can_see(), and tr_at().

Referenced by can_examine_at(), and vehicle::autodrive_controller::check_drivable().

◆ check_and_set_seen_cache()

bool map::check_and_set_seen_cache ( const tripoint p) const

Definition at line 8929 of file map.cpp.

8930{
8931 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
8933 if( !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ] ) {
8934 memory_seen_cache.set( static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) );
8935 return true;
8936 }
8937 return false;
8938}
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_seen_cache
Definition: map.h:351

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by draw_maptile().

◆ check_seen_cache()

bool map::check_seen_cache ( const tripoint p) const

Definition at line 8922 of file map.cpp.

8923{
8924 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
8926 return !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ];
8927}

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

◆ check_submap_active_item_consistency()

std::vector< tripoint > map::check_submap_active_item_consistency ( )

Definition at line 4651 of file map.cpp.

4652{
4653 std::vector<tripoint> result;
4654 for( int z = -OVERMAP_DEPTH; z < OVERMAP_HEIGHT; ++z ) {
4655 for( int x = 0; x < MAPSIZE; ++x ) {
4656 for( int y = 0; y < MAPSIZE; ++y ) {
4657 tripoint p( x, y, z );
4658 submap *s = get_submap_at_grid( p );
4659 bool has_active_items = !s->active_items.get().empty();
4660 bool map_has_active_items = submaps_with_active_items.count( p + abs_sub.xy() );
4661 if( has_active_items != map_has_active_items ) {
4662 result.push_back( p + abs_sub.xy() );
4663 }
4664 }
4665 }
4666 }
4667 for( const tripoint &p : submaps_with_active_items ) {
4668 tripoint rel = p - abs_sub.xy();
4670 if( !map.contains( rel.xy() ) ) {
4671 result.push_back( p );
4672 }
4673 }
4674 return result;
4675}
std::vector< item_reference > get()
Returns a vector of all cached active item references.
Manage and cache data about a part of the map.
Definition: map.h:384

References abs_sub, submap::active_items, active_item_cache::get(), get_submap_at_grid(), map(), MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, submaps_with_active_items, and tripoint::xy().

◆ check_vehicle_zones()

bool map::check_vehicle_zones ( int  zlev)

Definition at line 988 of file map.cpp.

989{
990 for( auto veh : get_cache( zlev ).zone_vehicles ) {
991 if( veh->zones_dirty ) {
992 return true;
993 }
994 }
995 return false;
996}

References get_cache().

Referenced by activity_on_turn_move_loot(), talk_function::basecamp_mission(), basecamp::distribute_food(), find_auto_consume(), basecamp::place_results(), and basecamp::validate_sort_points().

◆ clear_path()

bool map::clear_path ( const tripoint f,
const tripoint t,
int  range,
int  cost_min,
int  cost_max 
) const

Check whether there's a direct line of sight between F and T with the additional movecost restraints.

Checks two things:

  1. The sees() algorithm between F and T
  2. That moving over the line of sight would have a move_cost between cost_min and cost_max.

Definition at line 6505 of file map.cpp.

6507{
6508 // Ugly `if` for now
6509 if( !fov_3d && f.z != t.z ) {
6510 return false;
6511 }
6512
6513 if( f.z == t.z ) {
6514 if( ( range >= 0 && range < rl_dist( f.xy(), t.xy() ) ) ||
6515 !inbounds( t ) ) {
6516 return false; // Out of range!
6517 }
6518 bool is_clear = true;
6519 point last_point = f.xy();
6520 bresenham( f.xy(), t.xy(), 0,
6521 [this, &is_clear, cost_min, cost_max, &t, &last_point]( point new_point ) {
6522 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6523 if( new_point.x == t.x && new_point.y == t.y ) {
6524 return false;
6525 }
6526
6527 const int cost = this->move_cost( new_point );
6528 if( cost < cost_min || cost > cost_max ||
6529 obstructed_by_vehicle_rotation( tripoint( last_point, t.z ), tripoint( new_point,
6530 t.z ) ) ) {
6531 is_clear = false;
6532 return false;
6533 }
6534
6535 last_point = new_point;
6536 return true;
6537 } );
6538 return is_clear;
6539 }
6540
6541 if( ( range >= 0 && range < rl_dist( f, t ) ) ||
6542 !inbounds( t ) ) {
6543 return false; // Out of range!
6544 }
6545 bool is_clear = true;
6546 tripoint last_point = f;
6547 bresenham( f, t, 0, 0,
6548 [this, &is_clear, cost_min, cost_max, t, &last_point]( const tripoint & new_point ) {
6549 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6550 if( new_point == t ) {
6551 return false;
6552 }
6553
6554 // We have to check a weird case where the move is both vertical and horizontal
6555 if( new_point.z == last_point.z ) {
6556 const int cost = move_cost( new_point );
6557 if( cost < cost_min || cost > cost_max ||
6558 obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6559 is_clear = false;
6560 return false;
6561 }
6562 } else {
6563 bool this_clear = false;
6564 const int max_z = std::max( new_point.z, last_point.z );
6565 if( !has_floor_or_support( {new_point.xy(), max_z} ) ) {
6566 const int cost = move_cost( {new_point.xy(), last_point.z} );
6567 if( cost > cost_min && cost < cost_max &&
6568 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6569 this_clear = true;
6570 }
6571 }
6572
6573 if( !this_clear && has_floor_or_support( {last_point.xy(), max_z} ) ) {
6574 const int cost = move_cost( {last_point.xy(), new_point.z} );
6575 if( cost > cost_min && cost < cost_max &&
6576 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6577 this_clear = true;
6578 }
6579 }
6580
6581 if( !this_clear ) {
6582 is_clear = false;
6583 return false;
6584 }
6585 }
6586
6587 last_point = new_point;
6588 return true;
6589 } );
6590 return is_clear;
6591}
bool has_floor_or_support(const tripoint &p) const
Definition: map.cpp:2120
int move_cost(const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
Calculate the cost to move past the tile at p.
Definition: map.cpp:1844
void bresenham(point p1, point p2, int t, const std::function< bool(point)> &interact)
The actual Bresenham algorithm in 2D and 3D, everything else should call these and pass in an interac...
Definition: line.cpp:24

References bresenham(), fov_3d, inbounds(), obstructed_by_vehicle_rotation(), rl_dist(), tripoint::xy(), and tripoint::z.

Referenced by find_best_fire(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), points_for_gas_cloud(), process_fields_in_submap(), mattack::riotbot(), game::start_game(), and vehicle_selector::vehicle_selector().

◆ clear_spawns()

void map::clear_spawns ( )

Definition at line 7834 of file map.cpp.

7835{
7836 for( auto &smap : grid ) {
7837 smap->spawns.clear();
7838 }
7839}

References grid.

Referenced by defense_game::init_map().

◆ clear_traps()

void map::clear_traps ( )

Definition at line 7841 of file map.cpp.

7842{
7843 for( auto &smap : grid ) {
7844 for( int x = 0; x < SEEX; x++ ) {
7845 for( int y = 0; y < SEEY; y++ ) {
7846 const point p( x, y );
7847 smap->set_trap( p, tr_null );
7848 }
7849 }
7850 }
7851
7852 // Forget about all trap locations.
7853 for( auto &i : traplocs ) {
7854 i.clear();
7855 }
7856}

References grid, SEEX, SEEY, tr_null, and traplocs.

Referenced by defense_game::init_map().

◆ clear_vehicle_cache()

void map::clear_vehicle_cache ( )

Definition at line 372 of file map.cpp.

373{
374 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
375 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
376 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
377 level_cache &ch = get_cache( zlev );
378 while( !ch.veh_cached_parts.empty() ) {
379 const auto part = ch.veh_cached_parts.begin();
380 const auto &p = part->first;
381 if( inbounds( p ) ) {
382 ch.veh_exists_at[p.x][p.y] = false;
383 }
384 ch.veh_cached_parts.erase( part );
385 }
386 ch.veh_in_active_range = false;
387 }
388}

References abs_sub, get_cache(), inbounds(), OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by editmap::mapgen_preview(), game::place_player_overmap(), reset_vehicle_cache(), rotate(), shift(), and game::vertical_shift().

◆ clear_vehicle_list()

void map::clear_vehicle_list ( int  zlev)

Definition at line 390 of file map.cpp.

391{
392 auto &ch = get_cache( zlev );
393 ch.vehicle_list.clear();
394 ch.zone_vehicles.clear();
395
397}

References get_cache(), and last_full_vehicle_list_dirty.

Referenced by editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), game::place_player_overmap(), rotate(), and shift().

◆ clear_vehicle_point_from_cache()

void map::clear_vehicle_point_from_cache ( vehicle veh,
const tripoint pt 
)

Definition at line 354 of file map.cpp.

355{
356 if( veh == nullptr ) {
357 debugmsg( "Tried to clear null vehicle from cache" );
358 return;
359 }
360
361 level_cache &ch = get_cache( pt.z );
362 if( inbounds( pt ) ) {
363 ch.veh_exists_at[pt.x][pt.y] = false;
364 }
365 auto it = ch.veh_cached_parts.find( pt );
366 if( it != ch.veh_cached_parts.end() && it->second.first == veh ) {
367 ch.veh_cached_parts.erase( it );
368 }
369
370}

References debugmsg, get_cache(), inbounds(), level_cache::veh_cached_parts, level_cache::veh_exists_at, tripoint::x, tripoint::y, and tripoint::z.

Referenced by vehicle::advance_precalc_mounts(), veh_interact::complete_vehicle(), and vehicle::part_removal_cleanup().

◆ climb_difficulty()

int map::climb_difficulty ( const tripoint p) const

Checks 3x3 block centered on p for terrain to climb.

Returns
Difficulty of climbing check from point p.

Definition at line 2033 of file map.cpp.

2034{
2035 if( p.z > OVERMAP_HEIGHT || p.z < -OVERMAP_DEPTH ) {
2036 debugmsg( "climb_difficulty on out of bounds point: %d, %d, %d", p.x, p.y, p.z );
2037 return INT_MAX;
2038 }
2039
2040 int best_difficulty = INT_MAX;
2041 int blocks_movement = 0;
2042 if( has_flag( "LADDER", p ) ) {
2043 // Really easy, but you have to stand on the tile
2044 return 1;
2045 } else if( has_flag( TFLAG_RAMP, p ) || has_flag( TFLAG_RAMP_UP, p ) ||
2046 has_flag( TFLAG_RAMP_DOWN, p ) ) {
2047 // We're on something stair-like, so halfway there already
2048 best_difficulty = 7;
2049 }
2050
2051 for( const auto &pt : points_in_radius( p, 1 ) ) {
2052 if( impassable_ter_furn( pt ) ) {
2053 // TODO: Non-hardcoded climbability
2054 best_difficulty = std::min( best_difficulty, 10 );
2055 blocks_movement++;
2056 } else if( veh_at( pt ) ) {
2057 // Vehicle tiles are quite good for climbing
2058 // TODO: Penalize spiked parts?
2059 best_difficulty = std::min( best_difficulty, 7 );
2060 }
2061
2062 if( best_difficulty > 5 && has_flag( "CLIMBABLE", pt ) ) {
2063 best_difficulty = 5;
2064 }
2065 }
2066
2067 // TODO: Make this more sensible - check opposite sides, not just movement blocker count
2068 return std::max( 0, best_difficulty - blocks_movement );
2069}
bool impassable_ter_furn(const tripoint &p) const
Definition: map.cpp:1892
@ TFLAG_RAMP_UP
Definition: mapdata.h:313
@ TFLAG_RAMP
Definition: mapdata.h:314
@ TFLAG_RAMP_DOWN
Definition: mapdata.h:312

References debugmsg, has_flag(), impassable_ter_furn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, veh_at(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by map_funcs::climbing_cost().

◆ clip_to_bounds() [1/3]

void map::clip_to_bounds ( int &  x,
int &  y 
) const

Definition at line 9058 of file map.cpp.

9059{
9060 if( x < 0 ) {
9061 x = 0;
9062 } else if( x >= SEEX * my_MAPSIZE ) {
9063 x = SEEX * my_MAPSIZE - 1;
9064 }
9065
9066 if( y < 0 ) {
9067 y = 0;
9068 } else if( y >= SEEY * my_MAPSIZE ) {
9069 y = SEEY * my_MAPSIZE - 1;
9070 }
9071}

References my_MAPSIZE, SEEX, and SEEY.

◆ clip_to_bounds() [2/3]

void map::clip_to_bounds ( int &  x,
int &  y,
int &  z 
) const

Definition at line 9073 of file map.cpp.

9074{
9075 clip_to_bounds( x, y );
9076 if( z < -OVERMAP_DEPTH ) {
9077 z = -OVERMAP_DEPTH;
9078 } else if( z > OVERMAP_HEIGHT ) {
9079 z = OVERMAP_HEIGHT;
9080 }
9081}
void clip_to_bounds(tripoint &p) const
Clips the coordinates of p to fit the map bounds.
Definition: map.cpp:9053

References clip_to_bounds(), OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ clip_to_bounds() [3/3]

void map::clip_to_bounds ( tripoint p) const

Clips the coordinates of p to fit the map bounds.

Definition at line 9053 of file map.cpp.

9054{
9055 clip_to_bounds( p.x, p.y, p.z );
9056}

References clip_to_bounds(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by MapgenRemovePartHandler::add_item_or_charges(), clip_to_bounds(), and route().

◆ close_door()

bool map::close_door ( const tripoint p,
bool  inside,
bool  check_only 
)

Definition at line 4071 of file map.cpp.

4072{
4073 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
4074 return false;
4075 }
4076
4077 const auto &ter = this->ter( p ).obj();
4078 const auto &furn = this->furn( p ).obj();
4079 if( ter.close && !furn.id ) {
4080 if( !check_only ) {
4081 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
4082 "close_door", ter.id.str() );
4083 ter_set( p, ter.close );
4084 }
4085 return true;
4086 } else if( furn.close ) {
4087 if( !check_only ) {
4088 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
4089 "close_door", furn.id.str() );
4090 furn_set( p, furn.close );
4091 }
4092 return true;
4093 }
4094 return false;
4095}
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References _, furn(), furn_set(), has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), sounds::sound(), string_id< T >::str(), ter(), and ter_set().

Referenced by can_interact_at(), doors::close_door(), and game::try_get_right_click_action().

◆ collapse_at()

void map::collapse_at ( const tripoint p,
bool  silent,
bool  was_supporting = false,
bool  destroy_pos = true 
)

Causes a collapse at p, such as from destroying a wall.

Definition at line 2959 of file map.cpp.

2961{
2962 const bool supports = was_supporting || has_flag( TFLAG_SUPPORTS_ROOF, p );
2963 const bool wall = was_supporting || has_flag( TFLAG_WALL, p );
2964 // don't bash again if the caller already bashed here
2965 if( destroy_pos ) {
2966 destroy( p, silent );
2967 crush( p );
2968 make_rubble( p );
2969 }
2970 const bool still_supports = has_flag( TFLAG_SUPPORTS_ROOF, p );
2971
2972 // If something supporting the roof collapsed, see what else collapses
2973 if( supports && !still_supports ) {
2974 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2975 // If z-levels are off, tz == t, so we end up skipping a lot of stuff to avoid bugs.
2976 const tripoint &tz = tripoint( t.xy(), t.z + 1 );
2977 // if nothing above us had the chance of collapsing, move on
2978 if( !one_in( collapse_check( tz ) ) ) {
2979 continue;
2980 }
2981 // if a wall collapses, walls without support from below risk collapsing and
2982 //propagate the collapse upwards
2983 if( zlevels && wall && p == t && has_flag( TFLAG_WALL, tz ) ) {
2984 collapse_at( tz, silent );
2985 }
2986 // floors without support from below risk collapsing into open air and can propagate
2987 // the collapse horizontally but not vertically
2988 if( p != t && ( has_flag( TFLAG_SUPPORTS_ROOF, t ) && has_flag( TFLAG_COLLAPSES, t ) ) ) {
2989 collapse_at( t, silent );
2990 }
2991 // this tile used to support a roof, now it doesn't, which means there is only
2992 // open air above us
2993 if( zlevels ) {
2994 ter_set( tz, t_open_air );
2995 furn_set( tz, f_null );
2997 }
2998 }
2999 }
3000 // it would be great to check if collapsing ceilings smashed through the floor, but
3001 // that's not handled for now
3002}
void crush(const tripoint &p)
Definition: map.cpp:3767
int collapse_check(const tripoint &p)
Checks if a square should collapse, returns the X for the one_in(X) collapse chance.
Definition: map.cpp:2910
void make_rubble(const tripoint &p, const furn_id &rubble_type, const ter_id &floor_type, bool overwrite=false)
Generates rubble at the given location, if overwrite is true it just writes on top of what currently ...
Definition: map.cpp:2590
@ TFLAG_COLLAPSES
Definition: mapdata.h:288
@ TFLAG_WALL
Definition: mapdata.h:300

References collapse_at(), collapse_check(), crush(), destroy(), f_null, furn_set(), has_flag(), make_rubble(), one_in(), points_in_radius(), propagate_suspension_check(), silent, t_open_air, ter_set(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, and zlevels.

Referenced by bash_ter_success(), collapse_at(), and talk_function::loot_building().

◆ collapse_check()

int map::collapse_check ( const tripoint p)

Checks if a square should collapse, returns the X for the one_in(X) collapse chance.

Definition at line 2910 of file map.cpp.

2911{
2912 const bool collapses = has_flag( TFLAG_COLLAPSES, p );
2913 const bool supports_roof = has_flag( TFLAG_SUPPORTS_ROOF, p );
2914
2915 int num_supports = p.z == -OVERMAP_DEPTH ? 0 : -5;
2916 // if there's support below, things are less likely to collapse
2917 if( p.z > -OVERMAP_DEPTH ) {
2918 const tripoint &pbelow = tripoint( p.xy(), p.z - 1 );
2919 for( const tripoint &tbelow : points_in_radius( pbelow, 1 ) ) {
2920 if( has_flag( TFLAG_SUPPORTS_ROOF, pbelow ) ) {
2921 num_supports += 1;
2922 if( has_flag( TFLAG_WALL, pbelow ) ) {
2923 num_supports += 2;
2924 }
2925 if( tbelow == pbelow ) {
2926 num_supports += 2;
2927 }
2928 }
2929 }
2930 }
2931
2932 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2933 if( p == t ) {
2934 continue;
2935 }
2936
2937 if( collapses ) {
2938 if( has_flag( TFLAG_COLLAPSES, t ) ) {
2939 num_supports++;
2940 } else if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2941 num_supports += 2;
2942 }
2943 } else if( supports_roof ) {
2944 if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2945 if( has_flag( TFLAG_WALL, t ) ) {
2946 num_supports += 4;
2947 } else if( !has_flag( TFLAG_COLLAPSES, t ) ) {
2948 num_supports += 3;
2949 }
2950 }
2951 }
2952 }
2953
2954 return 1.7 * num_supports;
2955}

References has_flag(), OVERMAP_DEPTH, points_in_radius(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, tripoint::xy(), and tripoint::z.

Referenced by collapse_at().

◆ collapse_invalid_suspension()

void map::collapse_invalid_suspension ( const tripoint point)

Triggers a recursive collapse of suspended tiles based on their support validity.

Definition at line 3013 of file map.cpp.

3014{
3015 if( !is_suspension_valid( point ) ) {
3017 furn_set( point, f_null );
3018
3020 }
3021}
bool is_suspension_valid(const tripoint &point)
Checks the four orientations in which a suspended tile could be valid, and returns if the tile is val...
Definition: map.cpp:3023

References f_null, furn_set(), is_suspension_valid(), propagate_suspension_check(), t_open_air, and ter_set().

Referenced by drop_everything(), and propagate_suspension_check().

◆ combined_movecost()

int map::combined_movecost ( const tripoint from,
const tripoint to,
const vehicle ignored_vehicle = nullptr,
int  modifier = 0,
bool  flying = false,
bool  via_ramp = false 
) const

Cost to move out of one tile and into the next.

Returns
The cost in turns to move out of tripoint from and into to

Definition at line 1902 of file map.cpp.

1905{
1906 const int mults[4] = { 0, 50, 71, 100 };
1907 const int cost1 = move_cost( from, ignored_vehicle );
1908 const int cost2 = move_cost( to, ignored_vehicle );
1909 // Multiply cost depending on the number of differing axes
1910 // 0 if all axes are equal, 100% if only 1 differs, 141% for 2, 200% for 3
1911 size_t match = trigdist ? ( from.x != to.x ) + ( from.y != to.y ) + ( from.z != to.z ) : 1;
1912 if( flying || from.z == to.z ) {
1913 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1914 }
1915
1916 // Inter-z-level movement by foot (not flying)
1917 if( !valid_move( from, to, false, via_ramp ) ) {
1918 return 0;
1919 }
1920
1921 // TODO: Penalize for using stairs
1922 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1923}
bool valid_move(const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
Returns true if a creature could walk from from to to in one step.
Definition: map.cpp:1925

References move_cost(), trigdist, valid_move(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by npc::move_away_from(), npc::move_to(), and game::walk_move().

◆ computer_at()

computer * map::computer_at ( const tripoint p)

Definition at line 5652 of file map.cpp.

5653{
5654 if( !inbounds( p ) ) {
5655 return nullptr;
5656 }
5657
5658 point l;
5659 submap *const sm = get_submap_at( p, l );
5660 return sm->get_computer( l );
5661}

References get_submap_at(), inbounds(), and coords::sm.

Referenced by mission_start::reveal_lab_train_depot(), and game::use_computer().

◆ copy_grid()

void map::copy_grid ( const tripoint to,
const tripoint from 
)
protected

Definition at line 7619 of file map.cpp.

7620{
7621 const auto smap = get_submap_at_grid( from );
7622 setsubmap( get_nonant( to ), smap );
7623 for( auto &it : smap->vehicles ) {
7624 it->sm_pos = to;
7625 }
7626}
void setsubmap(size_t grididx, submap *smap)
Set the submap pointer in grid at the give index.
Definition: map.cpp:8417
size_t get_nonant(const tripoint &gridp) const
Get the index of a submap pointer in the grid given by grid coordinates.
Definition: map.cpp:8450

References get_nonant(), get_submap_at_grid(), and setsubmap().

Referenced by shift().

◆ could_see_items() [1/2]

bool map::could_see_items ( const tripoint p,
const Creature who 
) const

Check if the creature could see items at p if there were any items.

This is similar to sees_some_items, but it does not check that there are actually any items.

Definition at line 4844 of file map.cpp.

4845{
4846 return could_see_items( p, who.pos() );
4847}
virtual const tripoint & pos() const =0
bool could_see_items(const tripoint &p, const Creature &who) const
Check if the creature could see items at p if there were any items.
Definition: map.cpp:4844

References could_see_items(), and Creature::pos().

Referenced by could_see_items(), game::print_items_info(), and sees_some_items().

◆ could_see_items() [2/2]

bool map::could_see_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4849 of file map.cpp.

4850{
4851 static const std::string container_string( "CONTAINER" );
4852 const bool container = has_flag_ter_or_furn( container_string, p );
4853 const bool sealed = has_flag_ter_or_furn( TFLAG_SEALED, p );
4854 if( sealed && container ) {
4855 // never see inside of sealed containers
4856 return false;
4857 }
4858 if( container ) {
4859 // can see inside of containers if adjacent or
4860 // on top of the container
4861 return ( std::abs( p.x - from.x ) <= 1 &&
4862 std::abs( p.y - from.y ) <= 1 &&
4863 std::abs( p.z - from.z ) <= 1 );
4864 }
4865 return true;
4866}
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2403
@ TFLAG_SEALED
Definition: mapdata.h:285

References has_flag_ter_or_furn(), TFLAG_SEALED, tripoint::x, tripoint::y, and tripoint::z.

◆ coverage()

int map::coverage ( const tripoint p) const

Returns coverage value of the tile.

Definition at line 6354 of file map.cpp.

6355{
6356 if( const auto obstacle_f = furn( p ) ) {
6357 return obstacle_f->coverage;
6358 }
6359 if( const auto vp = veh_at( p ) ) {
6360 if( vp->obstacle_at_part() ) {
6361 return 60;
6362 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) &&
6363 !vp->part_with_feature( "PROTRUSION", true ) ) {
6364 return 45;
6365 }
6366 }
6367 return ter( p )->coverage;
6368}
@ VPFLAG_AISLE
Definition: veh_type.h:40

References map_data_common_t::coverage, furn(), ter(), veh_at(), and VPFLAG_AISLE.

Referenced by build_vision_transparency_cache(), and game::print_terrain_info().

◆ create_anomaly() [1/2]

void map::create_anomaly ( const tripoint p,
artifact_natural_property  prop,
bool  create_rubble = true 
)

Definition at line 6353 of file mapgen.cpp.

6354{
6355 // TODO: Z
6356 point c( cp.xy() );
6357 if( create_rubble ) {
6358 rough_circle( this, t_dirt, c, 11 );
6359 rough_circle_furn( this, f_rubble, c, 5 );
6360 furn_set( c, f_null );
6361 }
6362 switch( prop ) {
6363 case ARTPROP_WRIGGLING:
6364 case ARTPROP_MOVING:
6365 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6366 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6367 if( furn( point( i, j ) ) == f_rubble ) {
6368 add_field( {i, j, abs_sub.z}, fd_push_items, 1 );
6369 }
6370 }
6371 }
6372 break;
6373
6374 case ARTPROP_GLOWING:
6375 case ARTPROP_GLITTERING:
6376 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6377 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6378 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6379 mtrap_set( this, point( i, j ), tr_glow );
6380 }
6381 }
6382 }
6383 break;
6384
6385 case ARTPROP_HUMMING:
6386 case ARTPROP_RATTLING:
6387 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6388 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6389 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6390 mtrap_set( this, point( i, j ), tr_hum );
6391 }
6392 }
6393 }
6394 break;
6395
6396 case ARTPROP_WHISPERING:
6397 case ARTPROP_ENGRAVED:
6398 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6399 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6400 if( furn( point( i, j ) ) == f_rubble && one_in( 3 ) ) {
6401 mtrap_set( this, point( i, j ), tr_shadow );
6402 }
6403 }
6404 }
6405 break;
6406
6407 case ARTPROP_BREATHING:
6408 for( int i = c.x - 1; i <= c.x + 1; i++ ) {
6409 for( int j = c.y - 1; j <= c.y + 1; j++ ) {
6410 if( i == c.x && j == c.y ) {
6411 place_spawns( GROUP_BREATHER_HUB, 1, point( i, j ), point( i, j ), 1,
6412 true );
6413 } else {
6414 place_spawns( GROUP_BREATHER, 1, point( i, j ), point( i, j ), 1, true );
6415 }
6416 }
6417 }
6418 break;
6419
6420 case ARTPROP_DEAD:
6421 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6422 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6423 if( furn( point( i, j ) ) == f_rubble ) {
6424 mtrap_set( this, point( i, j ), tr_drain );
6425 }
6426 }
6427 }
6428 break;
6429
6430 case ARTPROP_ITCHY:
6431 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6432 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6433 if( furn( point( i, j ) ) == f_rubble ) {
6434 set_radiation( point( i, j ), rng( 0, 10 ) );
6435 }
6436 }
6437 }
6438 break;
6439
6440 case ARTPROP_ELECTRIC:
6441 case ARTPROP_CRACKLING:
6442 add_field( {c, abs_sub.z}, fd_shock_vent, 3 );
6443 break;
6444
6445 case ARTPROP_SLIMY:
6446 add_field( {c, abs_sub.z}, fd_acid_vent, 3 );
6447 break;
6448
6449 case ARTPROP_WARM:
6450 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6451 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6452 if( furn( point( i, j ) ) == f_rubble ) {
6453 add_field( {i, j, abs_sub.z}, fd_fire_vent, 1 + ( rl_dist( c, point( i, j ) ) % 3 ) );
6454 }
6455 }
6456 }
6457 break;
6458
6459 case ARTPROP_SCALED:
6460 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6461 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6462 if( furn( point( i, j ) ) == f_rubble ) {
6463 mtrap_set( this, point( i, j ), tr_snake );
6464 }
6465 }
6466 }
6467 break;
6468
6469 case ARTPROP_FRACTAL:
6470 create_anomaly( c + point( -4, -4 ),
6471 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6472 create_anomaly( c + point( 4, -4 ),
6473 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6474 create_anomaly( c + point( -4, 4 ),
6475 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6476 create_anomaly( c + point( 4, -4 ),
6477 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6478 break;
6479 default:
6480 break;
6481 }
6482}
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5506
void create_anomaly(const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
Definition: mapgen.cpp:6353
void set_radiation(const tripoint &p, int value)
Definition: map.cpp:4143
void place_spawns(const mongroup_id &group, int chance, point p1, point p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
Definition: mapgen.cpp:5423
artifact_natural_property
Definition: enums.h:152
@ ARTPROP_GLITTERING
Definition: enums.h:162
@ ARTPROP_ITCHY
Definition: enums.h:161
@ ARTPROP_RATTLING
Definition: enums.h:168
@ ARTPROP_WRIGGLING
Definition: enums.h:154
@ ARTPROP_HUMMING
Definition: enums.h:156
@ ARTPROP_WHISPERING
Definition: enums.h:158
@ ARTPROP_ENGRAVED
Definition: enums.h:165
@ ARTPROP_ELECTRIC
Definition: enums.h:163
@ ARTPROP_FRACTAL
Definition: enums.h:170
@ ARTPROP_SCALED
Definition: enums.h:169
@ ARTPROP_GLOWING
Definition: enums.h:155
@ ARTPROP_NULL
Definition: enums.h:153
@ ARTPROP_DEAD
Definition: enums.h:160
@ ARTPROP_BREATHING
Definition: enums.h:159
@ ARTPROP_MAX
Definition: enums.h:171
@ ARTPROP_CRACKLING
Definition: enums.h:166
@ ARTPROP_WARM
Definition: enums.h:167
@ ARTPROP_MOVING
Definition: enums.h:157
@ ARTPROP_SLIMY
Definition: enums.h:164
field_type_id fd_fire_vent
Definition: field_type.cpp:351
field_type_id fd_acid_vent
Definition: field_type.cpp:357
field_type_id fd_push_items
Definition: field_type.cpp:355
field_type_id fd_shock_vent
Definition: field_type.cpp:356
furn_id f_rubble
Definition: mapdata.cpp:1099
void rough_circle(map *m, const ter_id &type, point p, int rad)
Definition: mapgen.cpp:6517
static const mongroup_id GROUP_BREATHER("GROUP_BREATHER")
void rough_circle_furn(map *m, const furn_id &type, point p, int rad)
Definition: mapgen.cpp:6521
static const mongroup_id GROUP_BREATHER_HUB("GROUP_BREATHER_HUB")
void mtrap_set(map *m, point p, trap_id type)
static const trap_str_id tr_drain("tr_drain")
static const trap_str_id tr_snake("tr_snake")
static const trap_str_id tr_shadow("tr_shadow")
trap_id tr_glow
Definition: trap.cpp:312
trap_id tr_hum
Definition: trap.cpp:313

References abs_sub, add_field(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_DEAD, ARTPROP_ELECTRIC, ARTPROP_ENGRAVED, ARTPROP_FRACTAL, ARTPROP_GLITTERING, ARTPROP_GLOWING, ARTPROP_HUMMING, ARTPROP_ITCHY, ARTPROP_MAX, ARTPROP_MOVING, ARTPROP_NULL, ARTPROP_RATTLING, ARTPROP_SCALED, ARTPROP_SLIMY, ARTPROP_WARM, ARTPROP_WHISPERING, ARTPROP_WRIGGLING, c, create_anomaly(), f_null, f_rubble, fd_acid_vent, fd_fire_vent, fd_push_items, fd_shock_vent, furn(), furn_set(), GROUP_BREATHER, GROUP_BREATHER_HUB, mtrap_set(), one_in(), place_spawns(), rl_dist(), rng(), rough_circle(), rough_circle_furn(), set_radiation(), t_dirt, tr_drain, tr_glow, tr_hum, tr_shadow, tr_snake, tripoint::xy(), and tripoint::z.

Referenced by create_anomaly(), debug_menu::debug(), draw_lab(), and MapExtras::mx_portal_in().

◆ create_anomaly() [2/2]

void map::create_anomaly ( point  cp,
artifact_natural_property  prop,
bool  create_rubble = true 
)
inline

Definition at line 1333 of file map.h.

1333 {
1334 create_anomaly( tripoint( cp, abs_sub.z ), prop, create_rubble );
1335 }

References abs_sub, create_anomaly(), and tripoint::z.

◆ create_burnproducts()

void map::create_burnproducts ( const tripoint p,
const item fuel,
const units::mass burned_mass 
)

Definition at line 96 of file map_field.cpp.

97{
98 std::vector<material_id> all_mats = fuel.made_of();
99 if( all_mats.empty() ) {
100 return;
101 }
102 // Items that are multiple materials are assumed to be equal parts each.
103 const units::mass by_weight = burned_mass / all_mats.size();
104 for( material_id &mat : all_mats ) {
105 for( auto &bp : mat->burn_products() ) {
106 itype_id id = bp.first;
107 // Spawning the same item as the one that was just burned is pointless
108 // and leads to infinite recursion.
109 if( fuel.typeId() == id ) {
110 continue;
111 }
112 const float eff = bp.second;
113 const int n = std::floor( eff * ( by_weight / id->weight ) );
114
115 if( n <= 0 ) {
116 continue;
117 }
118 spawn_item( p, id, n, 1, calendar::turn );
119 }
120 }
121}
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4291
const std::string id
Definition: basecamp.h:87

References base_camps::id, item::made_of(), spawn_item(), calendar::turn, and item::typeId().

Referenced by MapExtras::burned_ground_parser(), and process_fields_in_submap().

◆ create_hot_air()

void map::create_hot_air ( const tripoint p,
int  intensity 
)
private

Definition at line 363 of file map_field.cpp.

364{
365 field_type_id hot_air;
366 switch( intensity ) {
367 case 1:
368 hot_air = fd_hot_air1;
369 break;
370 case 2:
371 hot_air = fd_hot_air2;
372 break;
373 case 3:
374 hot_air = fd_hot_air3;
375 break;
376 case 4:
377 hot_air = fd_hot_air4;
378 break;
379 default:
380 debugmsg( "Tried to spread hot air with intensity %d", intensity );
381 return;
382 }
383
384 for( int counter = 0; counter < 5; counter++ ) {
385 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
386 add_field( dst, hot_air, 1 );
387 }
388}
field_type_id fd_hot_air3
Definition: field_type.cpp:381
field_type_id fd_hot_air2
Definition: field_type.cpp:380
field_type_id fd_hot_air1
Definition: field_type.cpp:379
field_type_id fd_hot_air4
Definition: field_type.cpp:382

References add_field(), debugmsg, fd_hot_air1, fd_hot_air2, fd_hot_air3, fd_hot_air4, and rng().

Referenced by process_fields_in_submap().

◆ creature_in_field()

void map::creature_in_field ( Creature critter)

Apply field effects to the creature when it's on a square with fields.

Definition at line 1562 of file map_field.cpp.

1563{
1564 bool in_vehicle = false;
1565 bool inside_vehicle = false;
1566 player *u = critter.as_player();
1567 if( critter.is_monster() ) {
1568 monster_in_field( *static_cast<monster *>( &critter ) );
1569 } else {
1570 if( u ) {
1571 in_vehicle = u->in_vehicle;
1572 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1573 // and what part of the vehicle we need to deal with.
1574 if( in_vehicle ) {
1575 if( const optional_vpart_position vp = veh_at( u->pos() ) ) {
1576 if( vp->is_inside() ) {
1577 inside_vehicle = true;
1578 }
1579 }
1580 }
1581 player_in_field( *u );
1582 }
1583 }
1584
1585 field &curfield = get_field( critter.pos() );
1586 for( auto &field_entry_it : curfield ) {
1587 field_entry &cur_field_entry = field_entry_it.second;
1588 if( !cur_field_entry.is_field_alive() ) {
1589 continue;
1590 }
1591 const field_type_id cur_field_id = cur_field_entry.get_field_type();
1592
1593 for( const auto &fe : cur_field_entry.field_effects() ) {
1594 if( in_vehicle && fe.immune_in_vehicle ) {
1595 continue;
1596 }
1597 if( inside_vehicle && fe.immune_inside_vehicle ) {
1598 continue;
1599 }
1600 if( !inside_vehicle && fe.immune_outside_vehicle ) {
1601 continue;
1602 }
1603 if( in_vehicle && !one_in( fe.chance_in_vehicle ) ) {
1604 continue;
1605 }
1606 if( inside_vehicle && !one_in( fe.chance_inside_vehicle ) ) {
1607 continue;
1608 }
1609 if( !inside_vehicle && !one_in( fe.chance_outside_vehicle ) ) {
1610 continue;
1611 }
1612
1613 const effect field_fx = fe.get_effect();
1614 if( critter.is_immune_field( cur_field_id ) || critter.is_immune_effect( field_fx.get_id() ) ) {
1615 continue;
1616 }
1617 bool effect_added = false;
1618 if( fe.is_environmental ) {
1619 effect_added = critter.add_env_effect( fe.id, fe.bp->token, fe.intensity, fe.get_duration() );
1620 } else {
1621 effect_added = true;
1622 critter.add_effect( field_fx );
1623 }
1624 if( effect_added ) {
1625 critter.add_msg_player_or_npc( fe.env_message_type, fe.get_message(), fe.get_message_npc() );
1626 }
1627 }
1628 }
1629}
bool in_vehicle
Definition: character.h:1546
virtual bool is_monster() const
Definition: creature.h:101
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:327
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:685
virtual player * as_player()
Definition: creature.h:122
virtual bool is_immune_effect(const efftype_id &type) const =0
Definition: effect.h:161
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:305
std::vector< field_effect > field_effects() const
Definition: field.cpp:294
bool is_field_alive()
Definition: field.h:89
field_type_id get_field_type() const
Definition: field.cpp:105
A variable sized collection of field entries on a given map square.
Definition: field.h:131
void player_in_field(player &u)
Definition: map_field.cpp:1223
void monster_in_field(monster &z)
Definition: map_field.cpp:1631

References Creature::add_effect(), Creature::add_env_effect(), Creature::add_msg_player_or_npc(), Creature::as_player(), field_entry::field_effects(), get_field(), field_entry::get_field_type(), effect::get_id(), Character::in_vehicle, field_entry::is_field_alive(), Creature::is_immune_effect(), Creature::is_immune_field(), Creature::is_monster(), monster_in_field(), one_in(), player_in_field(), Creature::pos(), Character::pos(), and veh_at().

Referenced by add_field(), game::do_turn(), game::monmove(), npc::move_to(), and game::place_player().

◆ creature_on_trap()

void map::creature_on_trap ( Creature critter,
bool  may_avoid = true 
)

Apply trap effects to the creature, similar to creature_in_field.

If there is no trap at the creatures location, nothing is done. If the creature can avoid the trap, nothing is done as well. Otherwise the trap is triggered.

Parameters
critterCreature that just got trapped
may_avoidIf true, the creature tries to avoid the trap (Creature::avoid_trap). If false, the trap is always triggered.

Definition at line 8599 of file map.cpp.

8600{
8601 const auto &tr = tr_at( c.pos() );
8602 if( tr.is_null() ) {
8603 return;
8604 }
8605 // boarded in a vehicle means the player is above the trap, like a flying monster and can
8606 // never trigger the trap.
8607 const player *const p = dynamic_cast<const player *>( &c );
8608 if( p != nullptr && p->in_vehicle ) {
8609 return;
8610 }
8611 if( may_avoid && c.avoid_trap( c.pos(), tr ) ) {
8612 return;
8613 }
8614 tr.trigger( c.pos(), &c );
8615}

References c, Character::in_vehicle, and tr_at().

Referenced by game::fling_creature(), Character::knock_back_to(), monster::knock_back_to(), game::knockback(), iexamine::ledge(), npc::move_to(), game::phasing_move(), game::place_player(), mattack::ranged_pull(), smash(), teleport::teleport(), and game::vertical_move().

◆ crush()

void map::crush ( const tripoint p)

Definition at line 3767 of file map.cpp.

3768{
3769 player *crushed_player = g->critter_at<player>( p );
3770
3771 if( crushed_player != nullptr ) {
3772 bool player_inside = false;
3773 if( crushed_player->in_vehicle ) {
3774 const optional_vpart_position vp = veh_at( p );
3775 player_inside = vp && vp->is_inside();
3776 }
3777 if( !player_inside ) { //If there's a player at p and he's not in a covered vehicle...
3778 //This is the roof coming down on top of us, no chance to dodge
3779 crushed_player->add_msg_player_or_npc( m_bad, _( "You are crushed by the falling debris!" ),
3780 _( "<npcname> is crushed by the falling debris!" ) );
3781 // TODO: Make this depend on the ceiling material
3782 const int dam = rng( 0, 40 );
3783 // Torso and head take the brunt of the blow
3784 crushed_player->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH,
3785 dam * .25 ) );
3786 crushed_player->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH,
3787 dam * .45 ) );
3788 // Legs take the next most through transferred force
3789 crushed_player->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH,
3790 dam * .10 ) );
3791 crushed_player->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH,
3792 dam * .10 ) );
3793 // Arms take the least
3794 crushed_player->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH,
3795 dam * .05 ) );
3796 crushed_player->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH,
3797 dam * .05 ) );
3798
3799 // Pin whoever got hit
3800 crushed_player->add_effect( effect_crushed, 1_turns, num_bp );
3801 crushed_player->check_dead_state();
3802 }
3803 }
3804
3805 if( monster *const monhit = g->critter_at<monster>( p ) ) {
3806 // 25 ~= 60 * .45 (torso)
3807 monhit->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( 0, 25 ) ) );
3808
3809 // Pin whoever got hit
3810 monhit->add_effect( effect_crushed, 1_turns, num_bp );
3811 monhit->check_dead_state();
3812 }
3813
3814 if( const optional_vpart_position vp = veh_at( p ) ) {
3815 // Arbitrary number is better than collapsing house roof crushing APCs
3816 vp->vehicle().damage( vp->part_index(), rng( 100, 1000 ), DT_BASH, false );
3817 }
3818}
int_id< body_part_type > bodypart_id
Definition: bodypart.h:23
@ num_bp
Definition: bodypart.h:52
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1872
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:369
@ m_bad
Definition: enums.h:261
static const efftype_id effect_crushed("crushed")

References _, Creature::add_effect(), player::add_msg_player_or_npc(), Creature::check_dead_state(), Character::deal_damage(), DT_BASH, effect_crushed, g, Character::in_vehicle, m_bad, num_bp, rng(), and veh_at().

Referenced by collapse_at().

◆ dangerous_field_at()

bool map::dangerous_field_at ( const tripoint p)

Definition at line 5495 of file map.cpp.

5496{
5497 for( auto &pr : field_at( p ) ) {
5498 auto &fd = pr.second;
5499 if( fd.is_dangerous() ) {
5500 return true;
5501 }
5502 }
5503 return false;
5504}
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5397

References field_at().

Referenced by are_requirements_nearby(), and generic_multi_activity_locations().

◆ decay_cosmetic_fields()

void map::decay_cosmetic_fields ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Definition at line 7497 of file map.cpp.

7499{
7500 for( auto &pr : field_at( p ) ) {
7501 auto &fd = pr.second;
7502 const time_duration hl = fd.get_field_type().obj().half_life;
7503 if( !fd.decays_on_actualize() || hl <= 0_turns ) {
7504 continue;
7505 }
7506
7507 const time_duration added_age = 2 * time_since_last_actualize / rng( 2, 4 );
7508 fd.mod_field_age( added_age );
7509 const int intensity_drop = fd.get_field_age() / hl;
7510 if( intensity_drop > 0 ) {
7511 fd.set_field_intensity( fd.get_field_intensity() - intensity_drop );
7512 fd.mod_field_age( -hl * intensity_drop );
7513 }
7514 }
7515}

References field_at(), and rng().

Referenced by actualize().

◆ decay_fields_and_scent()

void map::decay_fields_and_scent ( const time_duration amount)

Moved here from weather.cpp for speed.

Decays fire, washable fields and scent. Washable fields are decayed only by 1/3 of the amount fire is.

Definition at line 2724 of file map.cpp.

2725{
2726 // TODO: Make this happen on all z-levels
2727
2728 // Decay scent separately, so that later we can use field count to skip empty submaps
2729 g->scent.decay();
2730
2731 // Coordinate code copied from lightmap calculations
2732 // TODO: Z
2733 const int smz = abs_sub.z;
2734 const auto &outside_cache = get_cache_ref( smz ).outside_cache;
2735 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
2736 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
2737 const auto cur_submap = get_submap_at_grid( { smx, smy, smz } );
2738 int to_proc = cur_submap->field_count;
2739 if( to_proc < 1 ) {
2740 if( to_proc < 0 ) {
2741 cur_submap->field_count = 0;
2742 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2743 << ( abs_sub + tripoint( smx, smy, 0 ) )
2744 << "has " << to_proc << " field_count";
2745 }
2746 get_cache( smz ).field_cache.reset( smx + ( smy * MAPSIZE ) );
2747 // This submap has no fields
2748 continue;
2749 }
2750
2751 for( int sx = 0; sx < SEEX; ++sx ) {
2752 if( to_proc < 1 ) {
2753 // This submap had some fields, but all got proc'd already
2754 break;
2755 }
2756
2757 for( int sy = 0; sy < SEEY; ++sy ) {
2758 const int x = sx + smx * SEEX;
2759 const int y = sy + smy * SEEY;
2760
2761 field &fields = cur_submap->get_field( { sx, sy} );
2762 if( !outside_cache[x][y] ) {
2763 to_proc -= fields.field_count();
2764 continue;
2765 }
2766
2767 for( auto &fp : fields ) {
2768 to_proc--;
2769 field_entry &cur = fp.second;
2770 const field_type_id type = cur.get_field_type();
2771 const int decay_amount_factor = type.obj().decay_amount_factor;
2772 if( decay_amount_factor != 0 ) {
2773 const time_duration decay_amount = amount / decay_amount_factor;
2774 cur.set_field_age( cur.get_field_age() + decay_amount );
2775 }
2776 }
2777 }
2778 }
2779
2780 if( to_proc > 0 ) {
2781 cur_submap->field_count = cur_submap->field_count - to_proc;
2782 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2783 << abs_sub + tripoint( smx, smy, 0 )
2784 << "has " << cur_submap->field_count - to_proc << "fields, but "
2785 << cur_submap->field_count << " field_count";
2786 }
2787 }
2788 }
2789}
time_duration set_field_age(const time_duration &new_age)
Sets age to the given value.
Definition: field.cpp:138
time_duration get_field_age() const
Definition: field.cpp:133
@ Error
Error (default: enabled).

References abs_sub, dbg, Error, level_cache::field_cache, submap::field_count, g, get_cache(), get_cache_ref(), field_entry::get_field_age(), field_entry::get_field_type(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, level_cache::outside_cache, SEEX, SEEY, field_entry::set_field_age(), sx, sy, type, and tripoint::z.

◆ delete_graffiti()

void map::delete_graffiti ( const tripoint p)

Definition at line 7929 of file map.cpp.

7930{
7931 if( !inbounds( p ) ) {
7932 return;
7933 }
7934 point l;
7935 submap *const current_submap = get_submap_at( p, l );
7936 current_submap->delete_graffiti( l );
7937}
void delete_graffiti(point p)
Definition: submap.cpp:144

References submap::delete_graffiti(), get_submap_at(), and inbounds().

◆ delete_signage()

void map::delete_signage ( const tripoint p) const

Definition at line 4119 of file map.cpp.

4120{
4121 if( !inbounds( p ) ) {
4122 return;
4123 }
4124
4125 point l;
4126 submap *const current_submap = get_submap_at( p, l );
4127
4128 current_submap->delete_signage( l );
4129}
void delete_signage(point p)
Definition: submap.cpp:183

References submap::delete_signage(), get_submap_at(), and inbounds().

Referenced by bash_furn_success(), construct::done_deconstruct(), and talk_function::loot_building().

◆ deregister_vehicle_zone()

bool map::deregister_vehicle_zone ( zone_data zone)

Definition at line 1022 of file map.cpp.

1023{
1024 if( const std::optional<vpart_reference> vp = veh_at( getlocal(
1025 zone.get_start_point() ) ).part_with_feature( "CARGO", false ) ) {
1026 auto bounds = vp->vehicle().loot_zones.equal_range( vp->mount() );
1027 for( auto it = bounds.first; it != bounds.second; it++ ) {
1028 if( &zone == &( it->second ) ) {
1029 vp->vehicle().loot_zones.erase( it );
1030 return true;
1031 }
1032 }
1033 }
1034 return false;
1035}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8387
tripoint get_start_point() const
Definition: clzones.h:314

References zone_data::get_start_point(), getlocal(), optional_vpart_position::part_with_feature(), and veh_at().

◆ destroy()

void map::destroy ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until it can't be bashed anymore.

Definition at line 3733 of file map.cpp.

3734{
3735 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3736 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3737
3738 // If we were destroying a floor, allow destroying floors
3739 // If we were destroying something unpassable, destroy only that
3740 bool was_impassable = impassable( p );
3741 int count = 0;
3742 while( count <= 25
3743 && bash( p, 999, silent, true ).success
3744 && ( !was_impassable || impassable( p ) ) ) {
3745 count++;
3746 }
3747}

References bash(), detail::count(), impassable(), silent, and behavior::success.

Referenced by add_vehicle_to_map(), bash(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), collapse_at(), draw_lab(), activity_handlers::jackhammer_finish(), make_rubble(), MapExtras::mx_crater(), MapExtras::mx_helicopter(), MapExtras::mx_supplydrop(), om_cutdown_trees(), activity_handlers::pickaxe_finish(), process_fields_in_submap(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ destroy_furn()

void map::destroy_furn ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until there is no more furniture.

Definition at line 3749 of file map.cpp.

3750{
3751 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3752 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3753 int count = 0;
3754 while( count <= 25 && furn( p ) != f_null && bash( p, 999, silent, true ).success ) {
3755 count++;
3756 }
3757}

References bash(), detail::count(), f_null, furn(), silent, and behavior::success.

Referenced by construct::done_grave(), and make_rubble().

◆ destroy_vehicle()

◆ detach_vehicle()

std::unique_ptr< vehicle > map::detach_vehicle ( vehicle veh)

Definition at line 413 of file map.cpp.

414{
415 if( veh == nullptr ) {
416 debugmsg( "map::detach_vehicle was passed nullptr" );
417 return std::unique_ptr<vehicle>();
418 }
419
420 int z = veh->sm_pos.z;
421 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
422 debugmsg( "detach_vehicle got a vehicle outside allowed z-level range! name=%s, submap:%d,%d,%d",
423 veh->name, veh->sm_pos.x, veh->sm_pos.y, veh->sm_pos.z );
424 // Try to fix by moving the vehicle here
425 z = veh->sm_pos.z = abs_sub.z;
426 }
427
428 // Unboard all passengers before detaching
429 for( auto const &part : veh->get_avail_parts( VPFLAG_BOARDABLE ) ) {
430 player *passenger = part.get_passenger();
431 if( passenger ) {
432 unboard_vehicle( part, passenger );
433 }
434 }
435 veh->invalidate_towing( true );
436 submap *const current_submap = get_submap_at_grid( veh->sm_pos );
437 level_cache &ch = get_cache( z );
438 for( size_t i = 0; i < current_submap->vehicles.size(); i++ ) {
439 if( current_submap->vehicles[i].get() == veh ) {
440 ch.vehicle_list.erase( veh );
441 ch.zone_vehicles.erase( veh );
443 std::unique_ptr<vehicle> result = std::move( current_submap->vehicles[i] );
444 current_submap->vehicles.erase( current_submap->vehicles.begin() + i );
445 if( veh->tracking_on ) {
447 }
448 dirty_vehicle_list.erase( veh );
449 veh->detach();
450 veh->refresh_position();
451 return result;
452 }
453 }
454 debugmsg( "detach_vehicle can't find it! name=%s, submap:%d,%d,%d", veh->name, veh->sm_pos.x,
455 veh->sm_pos.y, veh->sm_pos.z );
456 return std::unique_ptr<vehicle>();
457}
std::set< vehicle * > dirty_vehicle_list
Definition: map.h:1595
void reset_vehicle_cache()
Definition: map.cpp:313
void remove_vehicle(const vehicle *veh)
Remove the vehicle from being tracked in the overmap.
std::string name
Definition: vehicle.h:1874
void refresh_position()
Definition: vehicle.cpp:5817
bool tracking_on
Definition: vehicle.h:2016
void invalidate_towing(bool first_vehicle=false)
Definition: vehicle.cpp:6131
void detach()
Definition: vehicle.h:769
std::set< vehicle * > zone_vehicles
Definition: map.h:358
std::set< vehicle * > vehicle_list
Definition: map.h:357

References abs_sub, debugmsg, vehicle::detach(), dirty_vehicle_list, vehicle::get_avail_parts(), get_cache(), get_submap_at_grid(), vehicle::invalidate_towing(), avatar_action::move(), vehicle::name, overmap_buffer, OVERMAP_HEIGHT, vehicle::refresh_position(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), vehicle::sm_pos, vehicle::tracking_on, unboard_vehicle(), level_cache::vehicle_list, submap::vehicles, VPFLAG_BOARDABLE, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by add_vehicle_to_map(), destroy_vehicle(), and editmap::mapgen_veh_destroy().

◆ determine_wall_corner()

int map::determine_wall_corner ( const tripoint p) const
private

Definition at line 7960 of file map.cpp.

7961{
7962 int test_connect_group = ter( p ).obj().connect_group;
7963 uint8_t connections = get_known_connections( p, test_connect_group );
7964 // The bits in connections are SEWN, whereas the characters in LINE_
7965 // constants are NESW, so we want values in 8 | 2 | 1 | 4 order.
7966 switch( connections ) {
7967 case 8 | 2 | 1 | 4:
7968 return LINE_XXXX;
7969 case 0 | 2 | 1 | 4:
7970 return LINE_OXXX;
7971
7972 case 8 | 0 | 1 | 4:
7973 return LINE_XOXX;
7974 case 0 | 0 | 1 | 4:
7975 return LINE_OOXX;
7976
7977 case 8 | 2 | 0 | 4:
7978 return LINE_XXOX;
7979 case 0 | 2 | 0 | 4:
7980 return LINE_OXOX;
7981 case 8 | 0 | 0 | 4:
7982 return LINE_XOOX;
7983 case 0 | 0 | 0 | 4:
7984 return LINE_OXOX; // LINE_OOOX would be better
7985
7986 case 8 | 2 | 1 | 0:
7987 return LINE_XXXO;
7988 case 0 | 2 | 1 | 0:
7989 return LINE_OXXO;
7990 case 8 | 0 | 1 | 0:
7991 return LINE_XOXO;
7992 case 0 | 0 | 1 | 0:
7993 return LINE_XOXO; // LINE_OOXO would be better
7994 case 8 | 2 | 0 | 0:
7995 return LINE_XXOO;
7996 case 0 | 2 | 0 | 0:
7997 return LINE_OXOX; // LINE_OXOO would be better
7998 case 8 | 0 | 0 | 0:
7999 return LINE_XOXO; // LINE_XOOO would be better
8000
8001 case 0 | 0 | 0 | 0:
8002 return ter( p ).obj().symbol(); // technically just a column
8003
8004 default:
8005 // assert( false );
8006 // this shall not happen
8007 return '?';
8008 }
8009}
uint8_t get_known_connections(const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
Definition: map.cpp:1574
generic_factory< overmap_connection > connections("overmap connection")
#define LINE_XOXX
Definition: output.h:47
#define LINE_XOXO
Definition: output.h:39
#define LINE_OXOX
Definition: output.h:40
#define LINE_OOXX
Definition: output.h:43
#define LINE_OXXX
Definition: output.h:48
#define LINE_XXXO
Definition: output.h:45
#define LINE_XXOX
Definition: output.h:46
#define LINE_OXXO
Definition: output.h:42
#define LINE_XOOX
Definition: output.h:44
#define LINE_XXOO
Definition: output.h:41
#define LINE_XXXX
Definition: output.h:49
int symbol() const
Definition: mapdata.cpp:552

References map_data_common_t::connect_group, anonymous_namespace{overmap_connection.cpp}::connections, get_known_connections(), LINE_OOXX, LINE_OXOX, LINE_OXXO, LINE_OXXX, LINE_XOOX, LINE_XOXO, LINE_XOXX, LINE_XXOO, LINE_XXOX, LINE_XXXO, LINE_XXXX, int_id< T >::obj(), map_data_common_t::symbol(), and ter().

Referenced by draw_from_above(), and draw_maptile().

◆ disarm_trap()

void map::disarm_trap ( const tripoint p)
Perception increases chance of disarming trap Dexterity increases chance of disarming trap Traps increases chance of disarming trap

Definition at line 5313 of file map.cpp.

5314{
5315 const trap &tr = tr_at( p );
5316 if( tr.is_null() ) {
5317 debugmsg( "Tried to disarm a trap where there was none (%d %d %d)", p.x, p.y, p.z );
5318 return;
5319 }
5320
5321 const int tSkillLevel = g->u.get_skill_level( skill_traps );
5322 const int diff = tr.get_difficulty();
5323 int roll = rng( tSkillLevel, 4 * tSkillLevel );
5324
5325 // Some traps are not actual traps. Skip the rolls, different message and give the option to grab it right away.
5326 if( tr.get_avoidance() == 0 && tr.get_difficulty() == 0 ) {
5327 add_msg( _( "The %s is taken down." ), tr.name() );
5328 tr.on_disarmed( *this, p );
5329 return;
5330 }
5331
5332 ///\EFFECT_PER increases chance of disarming trap
5333
5334 ///\EFFECT_DEX increases chance of disarming trap
5335
5336 ///\EFFECT_TRAPS increases chance of disarming trap
5337 while( ( rng( 5, 20 ) < g->u.per_cur || rng( 1, 20 ) < g->u.dex_cur ) && roll < 50 ) {
5338 roll++;
5339 }
5340 if( roll >= diff ) {
5341 add_msg( _( "You disarm the trap!" ) );
5342 const int morale_buff = tr.get_avoidance() * 0.4 + tr.get_difficulty() + rng( 0, 4 );
5343 g->u.rem_morale( MORALE_FAILURE );
5344 g->u.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 );
5345 tr.on_disarmed( *this, p );
5346 if( diff > 1.25 * tSkillLevel ) { // failure might have set off trap
5347 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5348 }
5349 } else if( roll >= diff * .8 ) {
5350 add_msg( _( "You fail to disarm the trap." ) );
5351 const int morale_debuff = -rng( 6, 18 );
5352 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5353 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5354 if( diff > 1.25 * tSkillLevel ) {
5355 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5356 }
5357 } else {
5358 add_msg( m_bad, _( "You fail to disarm the trap, and you set it off!" ) );
5359 const int morale_debuff = -rng( 12, 24 );
5360 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5361 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5362 tr.trigger( p, &g->u );
5363 if( diff - roll <= 6 ) {
5364 // Give xp for failing, but not if we failed terribly (in which
5365 // case the trap may not be disarmable).
5366 g->u.practice( skill_traps, 2 * diff );
5367 }
5368 }
5369}
static const skill_id skill_traps("traps")
void add_msg(std::string msg)
Definition: messages.cpp:910
const morale_type MORALE_FAILURE("morale_failure")
const morale_type MORALE_ACCOMPLISHMENT("morale_accomplishment")
Definition: trap.h:86
std::string name() const
Definition: trap.cpp:177
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
void trigger(const tripoint &pos, Creature *creature=nullptr, item *item=nullptr) const
Trigger trap effects.
Definition: trap.cpp:232
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
void on_disarmed(map &m, const tripoint &p) const
Called when a trap at the given point in the map has been disarmed.
Definition: trap.cpp:260
int get_difficulty() const
This is used when disarming the trap.
Definition: trap.h:152

References _, add_msg(), debugmsg, g, trap::get_avoidance(), trap::get_difficulty(), trap::is_null(), m_bad, MORALE_ACCOMPLISHMENT, MORALE_FAILURE, trap::name(), trap::on_disarmed(), rng(), skill_traps, tr_at(), trap::trigger(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by iexamine::trap().

◆ disp_name()

std::string map::disp_name ( const tripoint p)

Definition at line 1394 of file map.cpp.

1395{
1396 return string_format( _( "the %s" ), name( p ) );
1397}

References _, name(), and string_format().

Referenced by vehicle::part_collision().

◆ displace_vehicle()

bool map::displace_vehicle ( vehicle veh,
const tripoint dp 
)

Definition at line 1183 of file map.cpp.

1184{
1185 const tripoint src = veh.global_pos3();
1186
1187 tripoint dst = src + dp;
1188
1189 if( !inbounds( src ) ) {
1190 add_msg( m_debug, "map::displace_vehicle: coordinates out of bounds %d,%d,%d->%d,%d,%d",
1191 src.x, src.y, src.z, dst.x, dst.y, dst.z );
1192 return false;
1193 }
1194
1195 point src_offset;
1196 point dst_offset;
1197 submap *src_submap = get_submap_at( src, src_offset );
1198 submap *dst_submap = get_submap_at( dst, dst_offset );
1199 std::set<int> smzs;
1200
1201 // first, let's find our position in current vehicles vector
1202 size_t our_i = 0;
1203 bool found = false;
1204 for( auto &smap : grid ) {
1205 for( size_t i = 0; i < smap->vehicles.size(); i++ ) {
1206 if( smap->vehicles[i].get() == &veh ) {
1207 our_i = i;
1208 src_submap = smap;
1209 found = true;
1210 break;
1211 }
1212 }
1213 if( found ) {
1214 break;
1215 }
1216 }
1217
1218 if( !found ) {
1219 add_msg( m_debug, "displace_vehicle [%s] failed", veh.name );
1220 return false;
1221 }
1222
1223 // move the vehicle
1224 // don't let it go off grid
1225 if( !inbounds( dst ) ) {
1226 veh.stop();
1227 // Silent debug
1228 dbg( DL::Error ) << "map:displace_vehicle: Stopping vehicle, displaced dp=" << dp;
1229 return true;
1230 }
1231
1232 // Need old coordinates to check for remote control
1233 const bool remote = veh.remote_controlled( g->u );
1234
1235 // record every passenger and pet inside
1236 std::vector<rider_data> riders = veh.get_riders();
1237
1238 bool need_update = false;
1239 bool z_change = false;
1240 int z_to = 0;
1241 // Move passengers and pets
1242 bool complete = false;
1243 // loop until everyone has moved or for each passenger
1244 for( size_t i = 0; !complete && i < riders.size(); i++ ) {
1245 complete = true;
1246 for( rider_data &r : riders ) {
1247 if( r.moved ) {
1248 continue;
1249 }
1250 const int prt = r.prt;
1251
1252 Creature *psg = r.psg;
1253 const tripoint part_pos = veh.global_part_pos3( prt );
1254 if( psg == nullptr ) {
1255 debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?",
1256 prt, part_pos.x, part_pos.y, part_pos.z,
1257 g->u.posx(), g->u.posy(), g->u.posz() );
1259 r.moved = true;
1260 continue;
1261 }
1262
1263 if( psg->pos() != part_pos ) {
1264 add_msg( m_debug, "Part/passenger position mismatch: part #%d at %d,%d,%d "
1265 "passenger at %d,%d,%d", prt, part_pos.x, part_pos.y, part_pos.z,
1266 psg->posx(), psg->posy(), psg->posz() );
1267 }
1268 const vehicle_part &veh_part = veh.part( prt );
1269
1270 tripoint next_pos = veh_part.precalc[1];
1271
1272 // Place passenger on the new part location
1273 tripoint psgp( dst + next_pos );
1274 // someone is in the way so try again
1275 if( g->critter_at( psgp ) ) {
1276 complete = false;
1277 continue;
1278 }
1279 if( psg->is_avatar() ) {
1280 // If passenger is you, we need to update the map
1281 need_update = true;
1282 z_change = psgp.z != part_pos.z;
1283 z_to = psgp.z;
1284 }
1285
1286 psg->setpos( psgp );
1287 r.moved = true;
1288 }
1289 }
1290
1291 veh.shed_loose_parts();
1292 smzs = veh.advance_precalc_mounts( dst_offset, src );
1293 if( src_submap != dst_submap ) {
1294 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
1295 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
1296 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
1297 src_submap->vehicles.erase( src_submap_veh_it );
1298 dst_submap->is_uniform = false;
1300 }
1301 if( need_update ) {
1302 g->update_map( g->u );
1303 }
1304 add_vehicle_to_cache( &veh );
1305
1306 if( z_change || src.z != dst.z ) {
1307 if( z_change ) {
1308 g->vertical_shift( z_to );
1309 // vertical moves can flush the caches, so make sure we're still in the cache
1310 add_vehicle_to_cache( &veh );
1311 }
1312 update_vehicle_list( dst_submap, dst.z );
1313 // delete the vehicle from the source z-level vehicle cache set if it is no longer on
1314 // that z-level
1315 if( src.z != dst.z ) {
1316 level_cache &ch2 = get_cache( src.z );
1317 for( const vehicle *elem : ch2.vehicle_list ) {
1318 if( elem == &veh ) {
1319 ch2.vehicle_list.erase( &veh );
1320 ch2.zone_vehicles.erase( &veh );
1321 break;
1322 }
1323 }
1324 }
1326 }
1327
1328 if( remote ) {
1329 // Has to be after update_map or coordinates won't be valid
1330 g->setremoteveh( &veh );
1331 }
1332
1333 //
1334 //global positions of vehicle loot zones have changed.
1335 veh.zones_dirty = true;
1336
1337 for( int vsmz : smzs ) {
1338 on_vehicle_moved( dst.z + vsmz );
1339 }
1340 return true;
1341}
virtual int posy() const =0
virtual int posz() const =0
virtual void setpos(const tripoint &pos)=0
virtual bool is_avatar() const
Definition: creature.h:95
virtual int posx() const =0
void on_vehicle_moved(int smz)
Callback invoked when a vehicle has moved.
Definition: map.cpp:464
void update_vehicle_list(const submap *to, int zlev)
Definition: map.cpp:399
tripoint global_pos3() const
Definition: vehicle.cpp:3282
bool check_is_heli_landed()
std::set< int > advance_precalc_mounts(point new_pos, const tripoint &src)
Definition: vehicle.cpp:7099
void shed_loose_parts()
Definition: vehicle.cpp:6259
std::vector< rider_data > get_riders() const
Definition: vehicle.cpp:3239
void stop(bool update_cache=true)
bool remote_controlled(const Character &p) const
Definition: vehicle.cpp:298
void set_submap_moved(const tripoint &p)
Update the submap coordinates and update the tracker info in the overmap (if enabled).
Definition: vehicle.cpp:3297
bool zones_dirty
Definition: vehicle.h:2032
@ m_debug
Definition: enums.h:271
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:186
std::array< tripoint, 2 > precalc
mount translated to face.dir [0] and turn_dir [1]
Definition: vehicle.h:372
int remove_flag(const int flag) noexcept
Definition: vehicle.h:215

References add_msg(), add_vehicle_to_cache(), vehicle::advance_precalc_mounts(), vehicle::check_is_heli_landed(), dbg, debugmsg, Error, g, get_cache(), vehicle::get_riders(), get_submap_at(), vehicle::global_part_pos3(), vehicle::global_pos3(), grid, inbounds(), invalidate_max_populated_zlev(), Creature::is_avatar(), submap::is_uniform, m_debug, avatar_action::move(), vehicle::name, on_vehicle_moved(), vehicle::part(), vehicle_part::passenger_flag, Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::precalc, vehicle::remote_controlled(), vehicle_part::remove_flag(), SEEX, SEEY, vehicle::set_submap_moved(), Creature::setpos(), vehicle::shed_loose_parts(), vehicle::stop(), update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, level_cache::zone_vehicles, and vehicle::zones_dirty.

Referenced by game::grabbed_veh_move(), and move_vehicle().

◆ displace_water()

bool map::displace_water ( const tripoint dp)

Definition at line 1343 of file map.cpp.

1344{
1345 // Check for shallow water
1346 if( has_flag( "SWIMMABLE", p ) && !has_flag( TFLAG_DEEP_WATER, p ) ) {
1347 int dis_places = 0;
1348 int sel_place = 0;
1349 for( int pass = 0; pass < 2; pass++ ) {
1350 // we do 2 passes.
1351 // first, count how many non-water places around
1352 // then choose one within count and fill it with water on second pass
1353 if( pass != 0 ) {
1354 sel_place = rng( 0, dis_places - 1 );
1355 dis_places = 0;
1356 }
1357 for( const tripoint &temp : points_in_radius( p, 1 ) ) {
1358 if( temp != p
1359 || impassable_ter_furn( temp )
1360 || has_flag( TFLAG_DEEP_WATER, temp ) ) {
1361 continue;
1362 }
1363 ter_id ter0 = ter( temp );
1364 if( ter0 == t_water_sh ||
1365 ter0 == t_water_dp || ter0 == t_water_moving_sh || ter0 == t_water_moving_dp ) {
1366 continue;
1367 }
1368 if( pass != 0 && dis_places == sel_place ) {
1369 ter_set( temp, t_water_sh );
1370 ter_set( temp, t_dirt );
1371 return true;
1372 }
1373
1374 dis_places++;
1375 }
1376 }
1377 }
1378 return false;
1379}
ter_id t_water_moving_dp
Definition: mapdata.cpp:695
ter_id t_water_moving_sh
Definition: mapdata.cpp:695
ter_id t_water_dp
Definition: mapdata.cpp:695
ter_id t_water_sh
Definition: mapdata.cpp:695

References has_flag(), impassable_ter_furn(), points_in_radius(), rng(), t_dirt, t_water_dp, t_water_moving_dp, t_water_moving_sh, t_water_sh, ter(), ter_set(), and TFLAG_DEEP_WATER.

Referenced by move_vehicle().

◆ do_vehicle_caching()

void map::do_vehicle_caching ( int  z)

Definition at line 8315 of file map.cpp.

8316{
8317 level_cache &ch = get_cache( z );
8318 for( vehicle *v : ch.vehicle_list ) {
8319 for( const vpart_reference &vp : v->get_all_parts() ) {
8320 const tripoint &part_pos = v->global_part_pos3( vp.part() );
8321 if( !inbounds( part_pos.xy() ) || vp.part().removed ) {
8322 continue;
8323 }
8324 vehicle_caching_internal( get_cache( part_pos.z ), vp, v );
8325 if( part_pos.z < OVERMAP_HEIGHT ) {
8326 vehicle_caching_internal_above( get_cache( part_pos.z + 1 ), vp, v );
8327 }
8328 }
8329 }
8330}
static void vehicle_caching_internal_above(level_cache &zch_above, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8306
static void vehicle_caching_internal(level_cache &zch, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8239

References vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), OVERMAP_HEIGHT, vehicle_caching_internal(), vehicle_caching_internal_above(), level_cache::vehicle_list, tripoint::xy(), and tripoint::z.

Referenced by build_map_cache().

◆ dont_draw_lower_floor()

bool map::dont_draw_lower_floor ( const tripoint p)

Definition at line 5969 of file map.cpp.

5970{
5971 return !zlevels || p.z <= -OVERMAP_DEPTH ||
5973}
@ TFLAG_Z_TRANSPARENT
Definition: mapdata.h:321

References has_flag(), OVERMAP_DEPTH, TFLAG_NO_FLOOR, TFLAG_Z_TRANSPARENT, tripoint::z, and zlevels.

◆ draw()

void map::draw ( const catacurses::window w,
const tripoint center 
)

Draw a visible part of the map into w.

This method uses g->u.posx()/posy() for visibility calculations, so it can not be used for anything but the player's viewport. Likewise, only g->m and maps with equivalent coordinates can be used, as other maps would have coordinate systems incompatible with g->u.posx()

Parameters
wWindow we are drawing in
centerThe coordinate of the center of the viewport, this can be different from the player coordinate.

Definition at line 5810 of file map.cpp.

5811{
5812 // We only need to draw anything if we're not in tiles mode.
5813 if( is_draw_tiles_mode() ) {
5814 return;
5815 }
5816
5817 g->reset_light_level();
5818
5821
5822 const auto &visibility_cache = get_cache_ref( center.z ).visibility_cache;
5823
5824 int wnd_h = getmaxy( w );
5825 int wnd_w = getmaxx( w );
5826 const tripoint offs = center - tripoint( wnd_w / 2, wnd_h / 2, 0 );
5827
5828 // Map memory should be at least the size of the view range
5829 // so that new tiles can be memorized, and at least the size of the terminal
5830 // since displayed area may be bigger than view range.
5831 const point min_mm_reg = point(
5832 std::min( 0, offs.x ),
5833 std::min( 0, offs.y )
5834 );
5835 const point max_mm_reg = point(
5836 std::max( MAPSIZE_X, offs.x + wnd_w ),
5837 std::max( MAPSIZE_Y, offs.y + wnd_h )
5838 );
5839 g->u.prepare_map_memory_region(
5840 g->m.getabs( tripoint( min_mm_reg, center.z ) ),
5841 g->m.getabs( tripoint( max_mm_reg, center.z ) )
5842 );
5843
5844 const auto draw_background = [&]( const tripoint & p ) {
5845 int sym = ' ';
5846 nc_color col = c_black;
5847 if( has_memory_at( p ) ) {
5848 sym = get_memory_at( p );
5849 col = c_brown;
5850 }
5851 wputch( w, col, sym );
5852 };
5853
5854 const auto draw_vision_effect = [&]( const visibility_type vis ) -> bool {
5855 int sym = '#';
5856 nc_color col;
5857 switch( vis )
5858 {
5859 case VIS_LIT:
5860 // can only tell that this square is bright
5861 col = c_light_gray;
5862 break;
5863 case VIS_BOOMER:
5864 col = c_pink;
5865 break;
5866 case VIS_BOOMER_DARK:
5867 col = c_magenta;
5868 break;
5869 default:
5870 return false;
5871 }
5872 wputch( w, col, sym );
5873 return true;
5874 };
5875
5876 drawsq_params params = drawsq_params().memorize( true );
5877 for( int wy = 0; wy < wnd_h; wy++ ) {
5878 for( int wx = 0; wx < wnd_w; wx++ ) {
5879 wmove( w, point( wx, wy ) );
5880 const tripoint p = offs + tripoint( wx, wy, 0 );
5881 if( !inbounds( p ) ) {
5882 draw_background( p );
5883 continue;
5884 }
5885
5886 const lit_level lighting = visibility_cache[p.x][p.y];
5887 const visibility_type vis = get_visibility( lighting, cache );
5888
5889 if( draw_vision_effect( vis ) ) {
5890 continue;
5891 }
5892
5893 if( vis == VIS_HIDDEN || vis == VIS_DARK ) {
5894 draw_background( p );
5895 continue;
5896 }
5897
5898 const maptile curr_maptile = maptile_at_internal( p );
5899 params
5900 .low_light( lighting == lit_level::LOW )
5901 .bright_light( lighting == lit_level::BRIGHT );
5902 if( draw_maptile( w, p, curr_maptile, params ) ) {
5903 continue;
5904 }
5905 const maptile tile_below = maptile_at_internal( p - tripoint_above );
5906 draw_from_above( w, tripoint( p.xy(), p.z - 1 ), tile_below, params );
5907 }
5908 }
5909
5910 // Memorize off-screen tiles
5911 half_open_rectangle<point> display( offs.xy(), offs.xy() + point( wnd_w, wnd_h ) );
5912 drawsq_params mm_params = drawsq_params().memorize( true ).output( false );
5913 for( int y = 0; y < MAPSIZE_Y; y++ ) {
5914 for( int x = 0; x < MAPSIZE_X; x++ ) {
5915 const tripoint p( x, y, center.z );
5916 if( display.contains( p.xy() ) ) {
5917 // Have been memorized during display loop
5918 continue;
5919 }
5920
5921 const lit_level lighting = visibility_cache[p.x][p.y];
5922 const visibility_type vis = get_visibility( lighting, cache );
5923
5924 if( vis != VIS_CLEAR ) {
5925 continue;
5926 }
5927
5928 const maptile curr_maptile = maptile_at_internal( p );
5929 mm_params
5930 .low_light( lighting == lit_level::LOW )
5931 .bright_light( lighting == lit_level::BRIGHT );
5932
5933 draw_maptile( w, p, curr_maptile, mm_params );
5934 }
5935 }
5936}
bool draw_maptile(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Internal version of the drawsq.
Definition: map.cpp:5975
visibility_type get_visibility(lit_level ll, const visibility_variables &cache) const
Definition: map.cpp:5760
void draw_from_above(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Draws the tile as seen from above.
Definition: map.cpp:6166
const visibility_variables & get_visibility_variables_cache() const
Definition: map.cpp:5755
void update_visibility_cache(int zlev)
Definition: map.cpp:5706
maptile maptile_at_internal(const tripoint &p) const
Definition: map.cpp:278
#define c_light_gray
Definition: color.h:19
#define c_black
Definition: color.h:17
#define c_magenta
Definition: color.h:25
#define c_brown
Definition: color.h:26
#define c_pink
Definition: color.h:31
visibility_type
Definition: enums.h:57
@ VIS_CLEAR
Definition: enums.h:59
@ VIS_BOOMER
Definition: enums.h:61
@ VIS_DARK
Definition: enums.h:62
@ VIS_BOOMER_DARK
Definition: enums.h:63
@ VIS_HIDDEN
Definition: enums.h:58
@ VIS_LIT
Definition: enums.h:60
lit_level
Definition: lightmap.h:43
static bool has_memory_at(const tripoint &p)
Definition: map.cpp:5793
static int get_memory_at(const tripoint &p)
Definition: map.cpp:5802
void wmove(const window &win, point p)
Definition: ncurses_def.cpp:98
int getmaxx(const window &win)
Definition: ncurses_def.cpp:58
int getmaxy(const window &win)
Definition: ncurses_def.cpp:63
static tripoint_abs_omt display(const tripoint_abs_omt &orig, const draw_data_t &data=draw_data_t())
bool is_draw_tiles_mode()
Check whether we're in tile drawing mode.
Definition: output.cpp:2075
void wputch(const catacurses::window &w, nc_color FG, int ch)
Definition: output.cpp:470
static constexpr tripoint tripoint_above
Definition: point.h:280
Draw parameters used by map::drawsq() and similar methods.
Definition: map.h:180
constexpr drawsq_params & bright_light(bool v)
Whether tile is in bright light.
Definition: map.h:240
constexpr drawsq_params & output(bool v)
HACK: Whether the tile should be printed.
Definition: map.h:269
constexpr drawsq_params & memorize(bool v)
Whether the tile should be memorized.
Definition: map.h:254
constexpr drawsq_params & low_light(bool v)
Whether tile is low light, and should be drawn with muted color.
Definition: map.h:226
lit_level visibility_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:350
A wrapper for a submap point.
Definition: submap.h:238

References BRIGHT, drawsq_params::bright_light(), c_black, c_brown, c_light_gray, c_magenta, c_pink, center, overmap_ui::display(), draw_from_above(), draw_maptile(), g, get_cache_ref(), get_memory_at(), get_visibility(), get_visibility_variables_cache(), catacurses::getmaxx(), catacurses::getmaxy(), has_memory_at(), inbounds(), is_draw_tiles_mode(), LOW, drawsq_params::low_light(), MAPSIZE_X, MAPSIZE_Y, maptile_at_internal(), drawsq_params::memorize(), drawsq_params::output(), tripoint_above, update_visibility_cache(), VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, VIS_LIT, level_cache::visibility_cache, catacurses::wmove(), wputch(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by advanced_inventory::draw_minimap(), and game::draw_ter().

◆ draw_anthill()

void map::draw_anthill ( mapgendata dat)
protected

Definition at line 5059 of file mapgen.cpp.

5060{
5061 const oter_id &terrain_type = dat.terrain_type();
5062 if( terrain_type == "anthill" || terrain_type == "acid_anthill" ) {
5063 for( int i = 0; i < SEEX * 2; i++ ) {
5064 for( int j = 0; j < SEEY * 2; j++ ) {
5065 if( i < 8 || j < 8 || i > SEEX * 2 - 9 || j > SEEY * 2 - 9 ) {
5066 ter_set( point( i, j ), dat.groundcover() );
5067 } else if( ( i == 11 || i == 12 ) && ( j == 11 || j == 12 ) ) {
5068 ter_set( point( i, j ), t_slope_down );
5069 } else {
5070 ter_set( point( i, j ), t_dirtmound );
5071 }
5072 }
5073 }
5074 }
5075}
const oter_id & terrain_type() const
Definition: mapgendata.h:87
ter_id groundcover()
Definition: mapgendata.cpp:141
ter_id t_slope_down
Definition: mapdata.cpp:720
ter_id t_dirtmound
Definition: mapdata.cpp:627

References mapgendata::groundcover(), SEEX, SEEY, t_dirtmound, t_slope_down, ter_set(), and mapgendata::terrain_type().

Referenced by draw_map().

◆ draw_circle_furn()

void map::draw_circle_furn ( const furn_id type,
point  p,
int  rad 
)

Definition at line 8566 of file map.cpp.

8567{
8568 draw_circle( [this, type]( point q ) {
8569 this->furn_set( q, type );
8570 }, p, rad );
8571}
void draw_circle(std::function< void(point)>set, const rl_vec2d &p, double rad)

References draw_circle(), furn_set(), rad, and type.

Referenced by circle_furn().

◆ draw_circle_ter() [1/2]

void map::draw_circle_ter ( const ter_id type,
const rl_vec2d p,
double  rad 
)

Definition at line 8552 of file map.cpp.

8553{
8554 draw_circle( [this, type]( point q ) {
8555 this->ter_set( q, type );
8556 }, p, rad );
8557}

References draw_circle(), rad, ter_set(), and type.

Referenced by circle().

◆ draw_circle_ter() [2/2]

void map::draw_circle_ter ( const ter_id type,
point  p,
int  rad 
)

Definition at line 8559 of file map.cpp.

8560{
8561 draw_circle( [this, type]( point q ) {
8562 this->ter_set( q, type );
8563 }, p, rad );
8564}

References draw_circle(), rad, ter_set(), and type.

◆ draw_connections()

void map::draw_connections ( mapgendata dat)
protected

Definition at line 5269 of file mapgen.cpp.

5270{
5271 const oter_id &terrain_type = dat.terrain_type();
5272 if( is_ot_match( "subway", terrain_type,
5273 ot_match_type::type ) ) { // FUUUUU it's IF ELIF ELIF ELIF's mini-me =[
5274 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) &&
5275 !connects_to( terrain_type, 0 ) ) {
5276 if( connects_to( dat.north(), 2 ) ) {
5277 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5278 for( int j = 0; j < SEEY; j++ ) {
5279 ter_set( point( i, j ), t_sewage );
5280 }
5281 }
5282 } else {
5283 for( int j = 0; j < 3; j++ ) {
5284 ter_set( point( SEEX, j ), t_rock_floor );
5285 ter_set( point( SEEX - 1, j ), t_rock_floor );
5286 }
5287 ter_set( point( SEEX, 3 ), t_door_metal_c );
5288 ter_set( point( SEEX - 1, 3 ), t_door_metal_c );
5289 }
5290 }
5291 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) &&
5292 !connects_to( terrain_type, 1 ) ) {
5293 if( connects_to( dat.east(), 3 ) ) {
5294 for( int i = SEEX; i < SEEX * 2; i++ ) {
5295 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5296 ter_set( point( i, j ), t_sewage );
5297 }
5298 }
5299 } else {
5300 for( int i = SEEX * 2 - 3; i < SEEX * 2; i++ ) {
5301 ter_set( point( i, SEEY ), t_rock_floor );
5302 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5303 }
5304 ter_set( point( SEEX * 2 - 4, SEEY ), t_door_metal_c );
5305 ter_set( point( SEEX * 2 - 4, SEEY - 1 ), t_door_metal_c );
5306 }
5307 }
5308 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) &&
5309 !connects_to( terrain_type, 2 ) ) {
5310 if( connects_to( dat.south(), 0 ) ) {
5311 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5312 for( int j = SEEY; j < SEEY * 2; j++ ) {
5313 ter_set( point( i, j ), t_sewage );
5314 }
5315 }
5316 } else {
5317 for( int j = SEEY * 2 - 3; j < SEEY * 2; j++ ) {
5318 ter_set( point( SEEX, j ), t_rock_floor );
5319 ter_set( point( SEEX - 1, j ), t_rock_floor );
5320 }
5321 ter_set( point( SEEX, SEEY * 2 - 4 ), t_door_metal_c );
5322 ter_set( point( SEEX - 1, SEEY * 2 - 4 ), t_door_metal_c );
5323 }
5324 }
5325 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) &&
5326 !connects_to( terrain_type, 3 ) ) {
5327 if( connects_to( dat.west(), 1 ) ) {
5328 for( int i = 0; i < SEEX; i++ ) {
5329 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5330 ter_set( point( i, j ), t_sewage );
5331 }
5332 }
5333 } else {
5334 for( int i = 0; i < 3; i++ ) {
5335 ter_set( point( i, SEEY ), t_rock_floor );
5336 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5337 }
5338 ter_set( point( 3, SEEY ), t_door_metal_c );
5339 ter_set( point( 3, SEEY - 1 ), t_door_metal_c );
5340 }
5341 }
5342 } else if( is_ot_match( "sewer", terrain_type, ot_match_type::type ) ) {
5343 if( dat.above() == "road_nesw_manhole" ) {
5344 ter_set( point( rng( SEEX - 2, SEEX + 1 ), rng( SEEY - 2, SEEY + 1 ) ), t_ladder_up );
5345 }
5346 if( is_ot_match( "subway", dat.north(), ot_match_type::type ) &&
5347 !connects_to( terrain_type, 0 ) ) {
5348 for( int j = 0; j < SEEY - 3; j++ ) {
5349 ter_set( point( SEEX, j ), t_rock_floor );
5350 ter_set( point( SEEX - 1, j ), t_rock_floor );
5351 }
5352 ter_set( point( SEEX, SEEY - 3 ), t_door_metal_c );
5353 ter_set( point( SEEX - 1, SEEY - 3 ), t_door_metal_c );
5354 }
5355 if( is_ot_match( "subway", dat.east(), ot_match_type::type ) &&
5356 !connects_to( terrain_type, 1 ) ) {
5357 for( int i = SEEX + 3; i < SEEX * 2; i++ ) {
5358 ter_set( point( i, SEEY ), t_rock_floor );
5359 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5360 }
5361 ter_set( point( SEEX + 2, SEEY ), t_door_metal_c );
5362 ter_set( point( SEEX + 2, SEEY - 1 ), t_door_metal_c );
5363 }
5364 if( is_ot_match( "subway", dat.south(), ot_match_type::type ) &&
5365 !connects_to( terrain_type, 2 ) ) {
5366 for( int j = SEEY + 3; j < SEEY * 2; j++ ) {
5367 ter_set( point( SEEX, j ), t_rock_floor );
5368 ter_set( point( SEEX - 1, j ), t_rock_floor );
5369 }
5370 ter_set( point( SEEX, SEEY + 2 ), t_door_metal_c );
5371 ter_set( point( SEEX - 1, SEEY + 2 ), t_door_metal_c );
5372 }
5373 if( is_ot_match( "subway", dat.west(), ot_match_type::type ) &&
5374 !connects_to( terrain_type, 3 ) ) {
5375 for( int i = 0; i < SEEX - 3; i++ ) {
5376 ter_set( point( i, SEEY ), t_rock_floor );
5377 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5378 }
5379 ter_set( point( SEEX - 3, SEEY ), t_door_metal_c );
5380 ter_set( point( SEEX - 3, SEEY - 1 ), t_door_metal_c );
5381 }
5382 } else if( is_ot_match( "ants", terrain_type, ot_match_type::type ) ) {
5383 if( dat.above() == "anthill" ) {
5384 if( const auto p = random_point( *this, [this]( const tripoint & n ) {
5385 return ter( n ) == t_rock_floor;
5386 } ) ) {
5387 ter_set( *p, t_slope_up );
5388 }
5389 }
5390 }
5391
5392 // finally, any terrain with SIDEWALKS should contribute sidewalks to neighboring diagonal roads
5393 if( terrain_type->has_flag( has_sidewalk ) ) {
5394 for( int dir = 4; dir < 8; dir++ ) { // NE SE SW NW
5395 bool n_roads_nesw[4] = {};
5396 int n_num_dirs = terrain_type_to_nesw_array( oter_id( dat.t_nesw[dir] ), n_roads_nesw );
5397 // only handle diagonal neighbors
5398 if( n_num_dirs == 2 &&
5399 n_roads_nesw[( ( dir - 4 ) + 3 ) % 4] &&
5400 n_roads_nesw[( ( dir - 4 ) + 2 ) % 4] ) {
5401 // make drawing simpler by rotating the map back and forth
5402 rotate( 4 - ( dir - 4 ) );
5403 // draw a small triangle of sidewalk in the northeast corner
5404 for( int y = 0; y < 4; y++ ) {
5405 for( int x = SEEX * 2 - 4; x < SEEX * 2; x++ ) {
5406 if( x - y > SEEX * 2 - 4 ) {
5407 // TODO: more discriminating conditions
5408 if( ter( point( x, y ) ) == t_grass || ter( point( x, y ) ) == t_dirt ||
5409 ter( point( x, y ) ) == t_shrub ) {
5410 ter_set( point( x, y ), t_sidewalk );
5411 }
5412 }
5413 }
5414 }
5415 rotate( ( dir - 4 ) );
5416 }
5417 }
5418 }
5419
5421}
void rotate(int turns, bool setpos_safe=false)
Rotates this map, and all of its contents, by the specified multiple of 90 degrees.
Definition: mapgen.cpp:5831
const oter_id & above() const
Definition: mapgendata.h:131
const oter_id & north() const
Definition: mapgendata.h:107
const oter_id & west() const
Definition: mapgendata.h:116
const oter_id & south() const
Definition: mapgendata.h:113
oter_id t_nesw[8]
Definition: mapgendata.h:45
const oter_id & east() const
Definition: mapgendata.h:110
std::optional< tripoint > random_point(const map &m, const std::function< bool(const tripoint &)> &predicate)
Same as other random_point with a range enclosing all valid points of the map.
ter_id t_grass
Definition: mapdata.cpp:630
ter_id t_sewage
Definition: mapdata.cpp:696
ter_id t_slope_up
Definition: mapdata.cpp:721
ter_id t_ladder_up
Definition: mapdata.cpp:720
ter_id t_shrub
Definition: mapdata.cpp:685
ter_id t_sidewalk
Definition: mapdata.cpp:632
ter_id t_door_metal_c
Definition: mapdata.cpp:664
bool connects_to(const oter_id &there, int dir)
Definition: mapgen.cpp:5933
void resolve_regional_terrain_and_furniture(const mapgendata &dat)
int terrain_type_to_nesw_array(oter_id terrain_type, bool array[4])
@ has_sidewalk
Definition: omdata.h:90
bool is_ot_match(const std::string &name, const oter_id &oter, const ot_match_type match_type)
Determine if the provided name is a match with the provided overmap terrain based on the specified ma...
Definition: overmap.cpp:568
bool has_flag(oter_flags flag) const
Definition: omdata.h:258

References mapgendata::above(), connects_to(), mapgendata::east(), oter_t::has_flag(), has_sidewalk, is_ot_match(), mapgendata::north(), oter_id, random_point(), resolve_regional_terrain_and_furniture(), rng(), rotate(), SEEX, SEEY, mapgendata::south(), t_dirt, t_door_metal_c, t_grass, t_ladder_up, mapgendata::t_nesw, t_rock_floor, t_sewage, t_shrub, t_sidewalk, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), terrain_type_to_nesw_array(), type, and mapgendata::west().

Referenced by draw_map().

◆ draw_fill_background() [1/3]

void map::draw_fill_background ( const ter_id type)

Definition at line 8481 of file map.cpp.

8482{
8483 // Need to explicitly set caches dirty - set_ter would do it before
8488
8489 // Fill each submap rather than each tile
8490 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
8491 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
8492 auto sm = get_submap_at_grid( {gridx, gridy} );
8493 sm->is_uniform = true;
8494 sm->set_all_ter( type );
8495 }
8496 }
8497}
void set_outside_cache_dirty(const int zlev)
Definition: map.cpp:221

References abs_sub, get_submap_at_grid(), my_MAPSIZE, set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), coords::sm, type, and tripoint::z.

Referenced by fill_background(), mapgendata::fill_groundcover(), mapgen_function_json::generate(), and mapgen_forest().

◆ draw_fill_background() [2/3]

void map::draw_fill_background ( const weighted_int_list< ter_id > &  f)

Definition at line 8503 of file map.cpp.

8504{
8506}
void draw_square_ter(const ter_id &type, point p1, point p2)
Definition: map.cpp:8508

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_fill_background() [3/3]

void map::draw_fill_background ( ter_id(*)()  f)

Definition at line 8499 of file map.cpp.

8500{
8502}

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_from_above()

void map::draw_from_above ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Draws the tile as seen from above.

Definition at line 6166 of file map.cpp.

6168{
6169 static const int AUTO_WALL_PLACEHOLDER = 2; // this should never appear as a real symbol!
6170
6171 nc_color tercol = c_dark_gray;
6172 int sym = ' ';
6173
6174 const ter_t &curr_ter = curr_tile.get_ter_t();
6175 const furn_t &curr_furn = curr_tile.get_furn_t();
6176 int part_below;
6177 const vehicle *veh;
6178 if( curr_furn.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6179 sym = curr_furn.symbol();
6180 tercol = curr_furn.color();
6181 } else if( curr_furn.movecost < 0 ) {
6182 sym = '.';
6183 tercol = curr_furn.color();
6184 } else if( ( veh = veh_at_internal( p, part_below ) ) != nullptr ) {
6185 const int roof = veh->roof_at_part( part_below );
6186 const int displayed_part = roof >= 0 ? roof : part_below;
6187 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( displayed_part, true ) ) );
6188 tercol = ( roof >= 0 ||
6189 vpart_position( const_cast<vehicle &>( *veh ),
6190 part_below ).obstacle_at_part() ) ? c_light_gray : c_light_gray_cyan;
6191 } else if( curr_ter.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6192 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
6193 sym = AUTO_WALL_PLACEHOLDER;
6194 } else if( curr_ter.has_flag( TFLAG_RAMP ) ) {
6195 sym = '>';
6196 } else {
6197 sym = curr_ter.symbol();
6198 }
6199 tercol = curr_ter.color();
6200 } else if( curr_ter.movecost == 0 ) {
6201 sym = '.';
6202 tercol = curr_ter.color();
6203 } else if( !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6204 sym = '.';
6205 if( curr_ter.color() != c_cyan ) {
6206 // Need a special case here, it doesn't cyanize well
6207 tercol = cyan_background( curr_ter.color() );
6208 } else {
6209 tercol = c_black_cyan;
6210 }
6211 } else {
6212 sym = curr_ter.symbol();
6213 tercol = curr_ter.color();
6214 }
6215
6216 if( sym == AUTO_WALL_PLACEHOLDER ) {
6217 sym = determine_wall_corner( p );
6218 }
6219
6220 const auto u_vision = g->u.get_vision_modes();
6221 if( u_vision[BOOMERED] ) {
6222 tercol = c_magenta;
6223 } else if( u_vision[NV_GOGGLES] ) {
6224 tercol = params.bright_light() ? c_white : c_light_green;
6225 } else if( params.low_light() ) {
6226 tercol = c_dark_gray;
6227 } else if( u_vision[DARKNESS] ) {
6228 tercol = c_dark_gray;
6229 }
6230
6231 if( params.highlight() ) {
6232 tercol = invert_color( tercol );
6233 }
6234
6235 if( params.output() ) {
6236 wputch( w, tercol, sym );
6237 }
6238}
@ DARKNESS
Definition: character.h:92
@ NV_GOGGLES
Definition: character.h:88
@ BOOMERED
Definition: character.h:91
int determine_wall_corner(const tripoint &p) const
Definition: map.cpp:7960
vehicle * veh_at_internal(const tripoint &p, int &part_num)
Definition: map.cpp:1108
int dir_symbol(int sym) const
Definition: tileray.cpp:113
char part_sym(int p, bool exact=false) const
int roof_at_part(int p) const
Definition: vehicle.cpp:3013
tileray face
Definition: vehicle.h:1973
std::optional< vpart_reference > obstacle_at_part() const
Returns the obstacle that exists at this point of the vehicle (if any).
Definition: vehicle.cpp:2439
nc_color invert_color(const nc_color &c)
Definition: color.cpp:503
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
#define c_white
Definition: color.h:18
#define c_light_green
Definition: color.h:28
#define c_dark_gray
Definition: color.h:20
#define c_black_cyan
Definition: color.h:154
#define c_cyan
Definition: color.h:24
#define c_light_gray_cyan
Definition: color.h:156
@ TFLAG_AUTO_WALL_SYMBOL
Definition: mapdata.h:305
@ TFLAG_SEEN_FROM_ABOVE
Definition: mapdata.h:311
int special_symbol(int sym)
Definition: output.cpp:1095
constexpr drawsq_params & highlight(bool v)
Highlight the tile.
Definition: map.h:198
nc_color color() const
Definition: mapdata.cpp:557

References BOOMERED, drawsq_params::bright_light(), c_black_cyan, c_cyan, c_dark_gray, c_light_gray, c_light_gray_cyan, c_light_green, c_magenta, c_white, map_data_common_t::color(), cyan_background(), DARKNESS, determine_wall_corner(), tileray::dir_symbol(), vehicle::face, g, maptile::get_furn_t(), maptile::get_ter_t(), map_data_common_t::has_flag(), drawsq_params::highlight(), invert_color(), drawsq_params::low_light(), map_data_common_t::movecost, NV_GOGGLES, vpart_position::obstacle_at_part(), drawsq_params::output(), vehicle::part_sym(), vehicle::roof_at_part(), special_symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_SEEN_FROM_ABOVE, veh_at_internal(), and wputch().

Referenced by draw(), and drawsq().

◆ draw_lab()

void map::draw_lab ( mapgendata dat)
protected

Definition at line 3544 of file mapgen.cpp.

3545{
3546 const oter_id &terrain_type = dat.terrain_type();
3547 // To distinguish between types of labs
3548 bool ice_lab = true;
3549 bool central_lab = false;
3550 bool tower_lab = false;
3551
3552 point p2;
3553
3554 int lw = 0;
3555 int rw = 0;
3556 int tw = 0;
3557 int bw = 0;
3558
3559 if( terrain_type == "lab" || terrain_type == "lab_stairs" || terrain_type == "lab_core" ||
3560 terrain_type == "ants_lab" || terrain_type == "ants_lab_stairs" ||
3561 terrain_type == "ice_lab" || terrain_type == "ice_lab_stairs" ||
3562 terrain_type == "ice_lab_core" ||
3563 terrain_type == "central_lab" || terrain_type == "central_lab_stairs" ||
3564 terrain_type == "central_lab_core" ||
3565 terrain_type == "tower_lab" || terrain_type == "tower_lab_stairs" ) {
3566
3567 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
3568 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
3569 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
3570
3571 if( ice_lab ) {
3572 int temperature = -20 + 30 * ( dat.zlevel() );
3574 set_temperature( p2 + point( SEEX, 0 ), temperature );
3575 set_temperature( p2 + point( 0, SEEY ), temperature );
3577 }
3578
3579 // Check for adjacent sewers; used below
3580 tw = 0;
3581 rw = 0;
3582 bw = 0;
3583 lw = 0;
3584 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) && connects_to( dat.north(), 2 ) ) {
3585 tw = SOUTH_EDGE + 1;
3586 }
3587 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) && connects_to( dat.east(), 3 ) ) {
3588 rw = EAST_EDGE + 1;
3589 }
3590 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) && connects_to( dat.south(), 0 ) ) {
3591 bw = SOUTH_EDGE + 1;
3592 }
3593 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) && connects_to( dat.west(), 1 ) ) {
3594 lw = EAST_EDGE + 1;
3595 }
3596 if( dat.zlevel() == 0 ) { // We're on ground level
3597 for( int i = 0; i < SEEX * 2; i++ ) {
3598 for( int j = 0; j < SEEY * 2; j++ ) {
3599 if( i <= 1 || i >= SEEX * 2 - 2 ||
3600 ( j > 1 && j < SEEY * 2 - 2 && ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3601 ter_set( point( i, j ), t_concrete_wall );
3602 } else if( j <= 1 || j >= SEEY * 2 - 2 ) {
3603 ter_set( point( i, j ), t_concrete_wall );
3604 } else {
3605 ter_set( point( i, j ), t_floor );
3606 }
3607 }
3608 }
3609 ter_set( point( SEEX - 1, 0 ), t_door_metal_locked );
3610 ter_set( point( SEEX - 1, 1 ), t_floor );
3612 ter_set( point( SEEX, 1 ), t_floor );
3613 ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), t_card_science );
3614 ter_set( point( SEEX - 2, SEEY ), t_door_metal_c );
3615 ter_set( point( SEEX + 1, SEEY ), t_door_metal_c );
3616 ter_set( point( SEEX - 2, SEEY - 1 ), t_door_metal_c );
3617 ter_set( point( SEEX + 1, SEEY - 1 ), t_door_metal_c );
3618 ter_set( point( SEEX - 1, SEEY * 2 - 3 ), t_stairs_down );
3619 ter_set( point( SEEX, SEEY * 2 - 3 ), t_stairs_down );
3620 science_room( this, point( 2, 2 ), point( SEEX - 3, SEEY * 2 - 3 ), dat.zlevel(), 1 );
3621 science_room( this, point( SEEX + 2, 2 ), point( SEEX * 2 - 3, SEEY * 2 - 3 ), dat.zlevel(), 3 );
3622
3623 place_spawns( GROUP_TURRET, 1, point( SEEX, 5 ), point( SEEX, 5 ), 1, true );
3624
3625 if( is_ot_match( "road", dat.east(), ot_match_type::type ) ) {
3626 rotate( 1 );
3627 } else if( is_ot_match( "road", dat.south(), ot_match_type::type ) ) {
3628 rotate( 2 );
3629 } else if( is_ot_match( "road", dat.west(), ot_match_type::type ) ) {
3630 rotate( 3 );
3631 }
3632 } else if( tw != 0 || rw != 0 || lw != 0 || bw != 0 ) { // Sewers!
3633 for( int i = 0; i < SEEX * 2; i++ ) {
3634 for( int j = 0; j < SEEY * 2; j++ ) {
3635 ter_set( point( i, j ), t_thconc_floor );
3636 if( ( ( i < lw || i > EAST_EDGE - rw ) && j > SEEY - 3 && j < SEEY + 2 ) ||
3637 ( ( j < tw || j > SOUTH_EDGE - bw ) && i > SEEX - 3 && i < SEEX + 2 ) ) {
3638 ter_set( point( i, j ), t_sewage );
3639 }
3640 if( ( i == 0 && is_ot_match( "lab", dat.east(), ot_match_type::contains ) ) || i == EAST_EDGE ) {
3641 if( ter( point( i, j ) ) == t_sewage ) {
3642 ter_set( point( i, j ), t_bars );
3643 } else if( j == SEEY - 1 || j == SEEY ) {
3644 ter_set( point( i, j ), t_door_metal_c );
3645 } else {
3646 ter_set( point( i, j ), t_concrete_wall );
3647 }
3648 } else if( ( j == 0 && is_ot_match( "lab", dat.north(), ot_match_type::contains ) ) ||
3649 j == SOUTH_EDGE ) {
3650 if( ter( point( i, j ) ) == t_sewage ) {
3651 ter_set( point( i, j ), t_bars );
3652 } else if( i == SEEX - 1 || i == SEEX ) {
3653 ter_set( point( i, j ), t_door_metal_c );
3654 } else {
3655 ter_set( point( i, j ), t_concrete_wall );
3656 }
3657 }
3658 }
3659 }
3660 } else { // We're below ground, and no sewers
3661 // Set up the boundaries of walls (connect to adjacent lab squares)
3662 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
3663 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
3664 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
3665 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
3666
3667 int boarders = 0;
3668 if( tw == 0 ) {
3669 boarders++;
3670 }
3671 if( rw == 1 ) {
3672 boarders++;
3673 }
3674 if( bw == 1 ) {
3675 boarders++;
3676 }
3677 if( lw == 0 ) {
3678 boarders++;
3679 }
3680
3681 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
3682 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
3683 const auto predicate = [this]( const tripoint & p ) {
3684 return ter( p ) == t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null();
3685 };
3686 const auto range = points_in_rectangle( { 0, 0, abs_sub.z }, { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
3687
3688 if( const auto p = random_point( range, predicate ) ) {
3689 ter_set( *p, t_stair_type );
3690 }
3691 }
3692 };
3693
3694 //A lab area with only one entrance
3695 if( boarders == 1 ) {
3696 // If you remove the usage of "lab_1side" here, remove it from mapgen_factory::get_usages above as well.
3697 if( oter_mapgen.generate( dat, "lab_1side" ) ) {
3698 if( tw == 2 ) {
3699 rotate( 2 );
3700 }
3701 if( rw == 2 ) {
3702 rotate( 1 );
3703 }
3704 if( lw == 2 ) {
3705 rotate( 3 );
3706 }
3707 } else {
3708 debugmsg( "Error: Tried to generate 1-sided lab but no lab_1side json exists." );
3709 }
3710 maybe_insert_stairs( dat.above(), t_stairs_up );
3711 maybe_insert_stairs( terrain_type, t_stairs_down );
3712 } else {
3713 const int hardcoded_4side_map_weight = 1500; // weight of all hardcoded maps.
3714 // If you remove the usage of "lab_4side" here, remove it from mapgen_factory::get_usages above as well.
3715 if( oter_mapgen.generate( dat, "lab_4side", hardcoded_4side_map_weight ) ) {
3716 // If the map template hasn't handled borders, handle them in code.
3717 // Rotated maps cannot handle borders and have to be caught in code.
3718 // We determine if a border isn't handled by checking the east-facing
3719 // border space where the door normally is -- it should be a wall or door.
3720 tripoint east_border( 23, 11, abs_sub.z );
3721 if( !has_flag_ter( "WALL", east_border ) &&
3722 !has_flag_ter( "DOOR", east_border ) ) {
3723 // TODO: create a ter_reset function that does ter_set,
3724 // furn_set, and i_clear?
3725 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3726 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3727 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass :
3729 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass :
3731 for( int i = 0; i < SEEX * 2; i++ ) {
3732 ter_set( point( 23, i ), rw_type );
3733 furn_set( point( 23, i ), f_null );
3734 i_clear( tripoint( 23, i, get_abs_sub().z ) );
3735
3736 ter_set( point( i, 23 ), bw_type );
3737 furn_set( point( i, 23 ), f_null );
3738 i_clear( tripoint( i, 23, get_abs_sub().z ) );
3739
3740 if( lw == 2 ) {
3741 ter_set( point( 0, i ), lw_type );
3742 furn_set( point( 0, i ), f_null );
3743 i_clear( tripoint( 0, i, get_abs_sub().z ) );
3744 }
3745 if( tw == 2 ) {
3746 ter_set( point( i, 0 ), tw_type );
3747 furn_set( point( i, 0 ), f_null );
3748 i_clear( tripoint( i, 0, get_abs_sub().z ) );
3749 }
3750 }
3751 if( rw != 2 ) {
3752 ter_set( point( 23, 11 ), t_door_metal_c );
3753 ter_set( point( 23, 12 ), t_door_metal_c );
3754 }
3755 if( bw != 2 ) {
3756 ter_set( point( 11, 23 ), t_door_metal_c );
3757 ter_set( point( 12, 23 ), t_door_metal_c );
3758 }
3759 }
3760
3761 maybe_insert_stairs( dat.above(), t_stairs_up );
3762 maybe_insert_stairs( terrain_type, t_stairs_down );
3763 } else { // then no json maps for lab_4side were found
3764 switch( rng( 1, 3 ) ) {
3765 case 1:
3766 // Cross shaped
3767 for( int i = 0; i < SEEX * 2; i++ ) {
3768 for( int j = 0; j < SEEY * 2; j++ ) {
3769 if( ( i < lw || i > EAST_EDGE - rw ) ||
3770 ( ( j < SEEY - 1 || j > SEEY ) &&
3771 ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3772 ter_set( point( i, j ), t_concrete_wall );
3773 } else if( ( j < tw || j > SOUTH_EDGE - bw ) ||
3774 ( ( i < SEEX - 1 || i > SEEX ) &&
3775 ( j == SEEY - 2 || j == SEEY + 1 ) ) ) {
3776 ter_set( point( i, j ), t_concrete_wall );
3777 } else {
3778 ter_set( point( i, j ), t_thconc_floor );
3779 }
3780 }
3781 }
3782 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3783 ter_set( point( rng( SEEX - 1, SEEX ), rng( SEEY - 1, SEEY ) ),
3784 t_stairs_up );
3785 }
3786 // Top left
3787 if( one_in( 2 ) ) {
3788 ter_set( point( SEEX - 2, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3789 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 1 );
3790 } else {
3792 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 2 );
3793 }
3794 // Top right
3795 if( one_in( 2 ) ) {
3796 ter_set( point( SEEX + 1, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3797 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3798 dat.zlevel(), 3 );
3799 } else {
3800 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 2 ), t_door_glass_frosted_c );
3801 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3802 dat.zlevel(), 2 );
3803 }
3804 // Bottom left
3805 if( one_in( 2 ) ) {
3807 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3808 dat.zlevel(), 0 );
3809 } else {
3810 ter_set( point( SEEX - 2, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3811 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3812 dat.zlevel(), 1 );
3813 }
3814 // Bottom right
3815 if( one_in( 2 ) ) {
3816 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 1 ), t_door_glass_frosted_c );
3817 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3818 dat.zlevel(), 0 );
3819 } else {
3820 ter_set( point( SEEX + 1, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3821 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3822 dat.zlevel(), 3 );
3823 }
3824 if( rw == 1 ) {
3827 }
3828 if( bw == 1 ) {
3831 }
3832 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { // Stairs going down
3833 std::vector<point> stair_points;
3834 if( tw != 0 ) {
3835 stair_points.push_back( point( SEEX - 1, 2 ) );
3836 stair_points.push_back( point( SEEX - 1, 2 ) );
3837 stair_points.push_back( point( SEEX, 2 ) );
3838 stair_points.push_back( point( SEEX, 2 ) );
3839 }
3840 if( rw != 1 ) {
3841 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3842 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3843 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3844 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3845 }
3846 if( bw != 1 ) {
3847 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3848 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3849 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3850 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3851 }
3852 if( lw != 0 ) {
3853 stair_points.push_back( point( 2, SEEY - 1 ) );
3854 stair_points.push_back( point( 2, SEEY - 1 ) );
3855 stair_points.push_back( point( 2, SEEY ) );
3856 stair_points.push_back( point( 2, SEEY ) );
3857 }
3858 stair_points.push_back( point( int( SEEX / 2 ), SEEY ) );
3859 stair_points.push_back( point( int( SEEX / 2 ), SEEY - 1 ) );
3860 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY ) );
3861 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY - 1 ) );
3862 stair_points.push_back( point( SEEX, int( SEEY / 2 ) ) );
3863 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) ) );
3864 stair_points.push_back( point( SEEX, int( SEEY / 2 ) + SEEY ) );
3865 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) + SEEY ) );
3866 const point p = random_entry( stair_points );
3867 ter_set( p, t_stairs_down );
3868 }
3869
3870 break;
3871
3872 case 2:
3873 // tic-tac-toe # layout
3874 for( int i = 0; i < SEEX * 2; i++ ) {
3875 for( int j = 0; j < SEEY * 2; j++ ) {
3876 if( i < lw || i > EAST_EDGE - rw || i == SEEX - 4 ||
3877 i == SEEX + 3 ) {
3878 ter_set( point( i, j ), t_concrete_wall );
3879 } else if( j < tw || j > SOUTH_EDGE - bw || j == SEEY - 4 ||
3880 j == SEEY + 3 ) {
3881 ter_set( point( i, j ), t_concrete_wall );
3882 } else {
3883 ter_set( point( i, j ), t_thconc_floor );
3884 }
3885 }
3886 }
3887 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3888 ter_set( point( SEEX - 1, SEEY - 1 ), t_stairs_up );
3889 ter_set( point( SEEX, SEEY - 1 ), t_stairs_up );
3890 ter_set( point( SEEX - 1, SEEY ), t_stairs_up );
3892 }
3893 ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), t_door_glass_frosted_c );
3894 ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), t_door_glass_frosted_c );
3895 ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3896 ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3897 ter_set( point( SEEX - 4, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3898 ter_set( point( SEEX + 3, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3901 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 4 ), t_door_glass_frosted_c );
3902 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 3 ), t_door_glass_frosted_c );
3903 ter_set( point( SEEX - 4, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3904 ter_set( point( SEEX + 3, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3905 science_room( this, point( lw, tw ), point( SEEX - 5, SEEY - 5 ), dat.zlevel(),
3906 rng( 1, 2 ) );
3907 science_room( this, point( SEEX - 3, tw ), point( SEEX + 2, SEEY - 5 ), dat.zlevel(), 2 );
3908 science_room( this, point( SEEX + 4, tw ), point( EAST_EDGE - rw, SEEY - 5 ),
3909 dat.zlevel(), rng( 2, 3 ) );
3910 science_room( this, point( lw, SEEY - 3 ), point( SEEX - 5, SEEY + 2 ), dat.zlevel(), 1 );
3911 science_room( this, point( SEEX + 4, SEEY - 3 ), point( EAST_EDGE - rw, SEEY + 2 ),
3912 dat.zlevel(), 3 );
3913 science_room( this, point( lw, SEEY + 4 ), point( SEEX - 5, SOUTH_EDGE - bw ),
3914 dat.zlevel(), rng( 0, 1 ) );
3915 science_room( this, point( SEEX - 3, SEEY + 4 ), point( SEEX + 2, SOUTH_EDGE - bw ),
3916 dat.zlevel(), 0 );
3917 science_room( this, point( SEEX + 4, SEEX + 4 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3918 dat.zlevel(), 3 * rng( 0, 1 ) );
3919 if( rw == 1 ) {
3922 }
3923 if( bw == 1 ) {
3926 }
3927 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) {
3928 ter_set( point( SEEX - 3 + 5 * rng( 0, 1 ), SEEY - 3 + 5 * rng( 0, 1 ) ),
3929 t_stairs_down );
3930 }
3931 break;
3932
3933 case 3:
3934 // Big room
3935 for( int i = 0; i < SEEX * 2; i++ ) {
3936 for( int j = 0; j < SEEY * 2; j++ ) {
3937 if( i < lw || i >= EAST_EDGE - rw ) {
3938 ter_set( point( i, j ), t_concrete_wall );
3939 } else if( j < tw || j >= SOUTH_EDGE - bw ) {
3940 ter_set( point( i, j ), t_concrete_wall );
3941 } else {
3942 ter_set( point( i, j ), t_thconc_floor );
3943 }
3944 }
3945 }
3946 science_room( this, point( lw, tw ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3947 dat.zlevel(), rng( 0, 3 ) );
3948
3949 if( rw == 1 ) {
3952 }
3953 if( bw == 1 ) {
3956 }
3957 maybe_insert_stairs( dat.above(), t_stairs_up );
3958 maybe_insert_stairs( terrain_type, t_stairs_down );
3959 break;
3960 }
3961 } // endif use_hardcoded_4side_map
3962 } // end 1 vs 4 sides
3963 } // end aboveground vs belowground
3964
3965 // Ants will totally wreck up the place
3966 if( is_ot_match( "ants", terrain_type, ot_match_type::contains ) ) {
3967 for( int i = 0; i < SEEX * 2; i++ ) {
3968 for( int j = 0; j < SEEY * 2; j++ ) {
3969 // Carve out a diamond area that covers 2 spaces on each edge.
3970 if( i + j > 10 && i + j < 36 && std::abs( i - j ) < 13 ) {
3971 // Doors and walls get sometimes destroyed:
3972 // 100% at the edge, usually in a central cross, occasionally elsewhere.
3973 if( ( has_flag_ter( "DOOR", point( i, j ) ) || has_flag_ter( "WALL", point( i, j ) ) ) ) {
3974 if( ( i == 0 || j == 0 || i == 23 || j == 23 ) ||
3975 ( !one_in( 3 ) && ( i == 11 || i == 12 || j == 11 || j == 12 ) ) ||
3976 one_in( 4 ) ) {
3977 // bash and usually remove the rubble.
3978 make_rubble( { i, j, abs_sub.z } );
3979 ter_set( point( i, j ), t_rock_floor );
3980 if( !one_in( 3 ) ) {
3981 furn_set( point( i, j ), f_null );
3982 }
3983 }
3984 // and then randomly destroy 5% of the remaining nonstairs.
3985 } else if( one_in( 20 ) &&
3986 !has_flag_ter( "GOES_DOWN", p2 ) &&
3987 !has_flag_ter( "GOES_UP", p2 ) ) {
3988 destroy( { i, j, abs_sub.z } );
3989 // bashed squares can create dirt & floors, but we want rock floors.
3990 if( t_dirt == ter( point( i, j ) ) || t_floor == ter( point( i, j ) ) ) {
3991 ter_set( point( i, j ), t_rock_floor );
3992 }
3993 }
3994 }
3995 }
3996 }
3997 }
3998
3999 // Slimes pretty much wreck up the place, too, but only underground
4000 tw = ( dat.north() == "slimepit" ? SEEY : 0 );
4001 rw = ( dat.east() == "slimepit" ? SEEX + 1 : 0 );
4002 bw = ( dat.south() == "slimepit" ? SEEY + 1 : 0 );
4003 lw = ( dat.west() == "slimepit" ? SEEX : 0 );
4004 if( tw != 0 || rw != 0 || bw != 0 || lw != 0 ) {
4005 for( int i = 0; i < SEEX * 2; i++ ) {
4006 for( int j = 0; j < SEEY * 2; j++ ) {
4007 if( ( ( j <= tw || i >= rw ) && i >= j && ( EAST_EDGE - i ) <= j ) ||
4008 ( ( j >= bw || i <= lw ) && i <= j && ( SOUTH_EDGE - j ) <= i ) ) {
4009 if( one_in( 5 ) ) {
4011 t_slime );
4012 } else if( !one_in( 5 ) ) {
4013 ter_set( point( i, j ), t_slime );
4014 }
4015 }
4016 }
4017 }
4018 }
4019
4020 int light_odds = 0;
4021 // central labs are always fully lit, other labs have half chance of some lights.
4022 if( central_lab ) {
4023 light_odds = 1;
4024 } else if( one_in( 2 ) ) {
4025 // Create a spread of densities, from all possible lights on, to 1/3, ...
4026 // to ~1 per segment.
4027 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4028 }
4029 if( light_odds > 0 ) {
4030 for( int i = 0; i < SEEX * 2; i++ ) {
4031 for( int j = 0; j < SEEY * 2; j++ ) {
4032 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4033 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4035 }
4036 }
4037 }
4038 }
4039 }
4040
4041 if( tower_lab ) {
4043 }
4044
4045 // Lab special effects.
4046 if( one_in( 10 ) ) {
4047 switch( rng( 1, 7 ) ) {
4048 // full flooding/sewage
4049 case 1: {
4050 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4051 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4052 // don't flood if stairs because the floor below will not be flooded.
4053 // don't flood if ice lab because there's no mechanic for freezing
4054 // liquid floors.
4055 break;
4056 }
4057 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4058 for( int i = 0; i < EAST_EDGE; i++ ) {
4059 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4060 // We spare some terrain to make it look better visually.
4061 if( !one_in( 10 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4062 t_strconc_floor == ter( point( i, j ) ) ||
4063 t_thconc_floor_olight == ter( point( i, j ) ) ) ) {
4064 ter_set( point( i, j ), fluid_type );
4065 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 3 ) ) {
4066 // We want the actual debris, but not the rubble marker or dirt.
4067 make_rubble( { i, j, abs_sub.z } );
4068 ter_set( point( i, j ), fluid_type );
4069 furn_set( point( i, j ), f_null );
4070 }
4071 }
4072 }
4073 break;
4074 }
4075 // minor flooding/sewage
4076 case 2: {
4077 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4078 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4079 // don't flood if stairs because the floor below will not be flooded.
4080 // don't flood if ice lab because there's no mechanic for freezing
4081 // liquid floors.
4082 break;
4083 }
4084 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4085 for( int i = 0; i < 2; ++i ) {
4086 draw_rough_circle( [this, fluid_type]( point p ) {
4087 if( t_thconc_floor == ter( p ) || t_strconc_floor == ter( p ) ||
4088 t_thconc_floor_olight == ter( p ) ) {
4089 ter_set( p, fluid_type );
4090 } else if( has_flag_ter( "DOOR", p ) ) {
4091 // We want the actual debris, but not the rubble marker or dirt.
4092 make_rubble( { p, abs_sub.z } );
4093 ter_set( p, fluid_type );
4094 furn_set( p, f_null );
4095 }
4096 }, point( rng( 1, SEEX * 2 - 2 ), rng( 1, SEEY * 2 - 2 ) ), rng( 3, 6 ) );
4097 }
4098 break;
4099 }
4100 // toxic gas leaks and smoke-filled rooms.
4101 case 3:
4102 case 4: {
4103 bool is_toxic = one_in( 3 );
4104 for( int i = 0; i < SEEX * 2; i++ ) {
4105 for( int j = 0; j < SEEY * 2; j++ ) {
4106 if( one_in( 200 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4107 t_strconc_floor == ter( point( i, j ) ) ) ) {
4108 if( is_toxic ) {
4109 add_field( {i, j, abs_sub.z}, fd_gas_vent, 1 );
4110 } else {
4111 add_field( {i, j, abs_sub.z}, fd_smoke_vent, 2 );
4112 }
4113 }
4114 }
4115 }
4116 break;
4117 }
4118 // portal with an artifact effect.
4119 case 5: {
4120 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4121 std::vector<artifact_natural_property> valid_props = {
4128 };
4129 draw_rough_circle( [this]( point p ) {
4130 if( has_flag_ter( "GOES_DOWN", p ) ||
4131 has_flag_ter( "GOES_UP", p ) ||
4132 has_flag_ter( "CONSOLE", p ) ) {
4133 return; // spare stairs and consoles.
4134 }
4135 make_rubble( {p, abs_sub.z } );
4136 ter_set( p, t_thconc_floor );
4137 }, center.xy(), 4 );
4138 furn_set( center.xy(), f_null );
4140 create_anomaly( center, random_entry( valid_props ), false );
4141 break;
4142 }
4143 // radioactive accident.
4144 case 6: {
4145 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4146 if( has_flag_ter( "WALL", center.xy() ) ) {
4147 // just skip it, we don't want to risk embedding radiation out of sight.
4148 break;
4149 }
4150 draw_rough_circle( [this]( point p ) {
4151 set_radiation( p, 10 );
4152 }, center.xy(), rng( 7, 12 ) );
4153 draw_circle( [this]( point p ) {
4154 set_radiation( p, 20 );
4155 }, center.xy(), rng( 5, 8 ) );
4156 draw_circle( [this]( point p ) {
4157 set_radiation( p, 30 );
4158 }, center.xy(), rng( 2, 4 ) );
4159 draw_circle( [this]( point p ) {
4160 set_radiation( p, 50 );
4161 }, center.xy(), 1 );
4162 draw_circle( [this]( point p ) {
4163 if( has_flag_ter( "GOES_DOWN", p ) ||
4164 has_flag_ter( "GOES_UP", p ) ||
4165 has_flag_ter( "CONSOLE", p ) ) {
4166 return; // spare stairs and consoles.
4167 }
4168 make_rubble( {p, abs_sub.z } );
4169 ter_set( p, t_thconc_floor );
4170 }, center.xy(), 1 );
4171
4173 center.xy() + point_west, 1, true );
4175 center.xy() + point_west, 1, true );
4176
4177 // damaged mininuke/plut thrown past edge of rubble so the player can see it.
4178 int marker_x = center.x - 2 + 4 * rng( 0, 1 );
4179 int marker_y = center.y + rng( -2, 2 );
4180 if( one_in( 4 ) ) {
4181 spawn_item(
4182 point( marker_x, marker_y ), "mininuke", 1, 1, calendar::start_of_cataclysm, rng( 2, 4 )
4183 );
4184 } else {
4185 item newliquid( "plut_slurry_dense", calendar::start_of_cataclysm );
4186 newliquid.charges = 1;
4187 add_item_or_charges( tripoint( marker_x, marker_y, get_abs_sub().z ),
4188 newliquid );
4189 }
4190 break;
4191 }
4192 // portal with fungal invasion
4193 case 7: {
4194 for( int i = 0; i < EAST_EDGE; i++ ) {
4195 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4196 // Create a mostly spread fungal area throughout entire lab.
4197 if( !one_in( 5 ) && ( has_flag( "FLAT", point( i, j ) ) ) ) {
4198 ter_set( point( i, j ), t_fungus_floor_in );
4199 if( has_flag_furn( "ORGANIC", point( i, j ) ) ) {
4200 furn_set( point( i, j ), f_fungal_clump );
4201 }
4202 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 5 ) ) {
4203 ter_set( point( i, j ), t_fungus_floor_in );
4204 } else if( has_flag_ter( "WALL", point( i, j ) ) && one_in( 3 ) ) {
4205 ter_set( point( i, j ), t_fungus_wall );
4206 }
4207 }
4208 }
4209 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4210
4211 // Make a portal surrounded by more dense fungal stuff and a fungaloid.
4212 draw_rough_circle( [this]( point p ) {
4213 if( has_flag_ter( "GOES_DOWN", p ) ||
4214 has_flag_ter( "GOES_UP", p ) ||
4215 has_flag_ter( "CONSOLE", p ) ) {
4216 return; // spare stairs and consoles.
4217 }
4218 if( has_flag_ter( "WALL", p ) ) {
4219 ter_set( p, t_fungus_wall );
4220 } else {
4222 if( one_in( 3 ) ) {
4224 } else if( one_in( 10 ) ) {
4225 ter_set( p, t_marloss );
4226 }
4227 }
4228 }, center.xy(), 3 );
4230 furn_set( center.xy(), f_null );
4232 place_spawns( GROUP_FUNGI_FUNGALOID, 1, center.xy() + point( -2, -2 ),
4233 center.xy() + point( 2, 2 ), 1, true );
4234
4235 break;
4236 }
4237 }
4238 }
4239 } else if( terrain_type == "lab_finale" || terrain_type == "ice_lab_finale" ||
4240 terrain_type == "central_lab_finale" || terrain_type == "tower_lab_finale" ) {
4241
4242 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
4243 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
4244 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
4245
4246 if( ice_lab ) {
4247 int temperature = -20 + 30 * dat.zlevel();
4249 set_temperature( p2 + point( SEEX, 0 ), temperature );
4250 set_temperature( p2 + point( 0, SEEY ), temperature );
4252 }
4253
4254 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
4255 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
4256 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
4257 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
4258
4259 const int hardcoded_finale_map_weight = 500; // weight of all hardcoded maps.
4260 // If you remove the usage of "lab_finale_1level" here, remove it from mapgen_factory::get_usages above as well.
4261 if( oter_mapgen.generate( dat, "lab_finale_1level", hardcoded_finale_map_weight ) ) {
4262 // If the map template hasn't handled borders, handle them in code.
4263 // Rotated maps cannot handle borders and have to be caught in code.
4264 // We determine if a border isn't handled by checking the east-facing
4265 // border space where the door normally is -- it should be a wall or door.
4266 tripoint east_border( 23, 11, abs_sub.z );
4267 if( !has_flag_ter( "WALL", east_border ) && !has_flag_ter( "DOOR", east_border ) ) {
4268 // TODO: create a ter_reset function that does ter_set, furn_set, and i_clear?
4269 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4270 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4271 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : t_concrete_wall;
4272 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : t_concrete_wall;
4273 for( int i = 0; i < SEEX * 2; i++ ) {
4274 ter_set( point( 23, i ), rw_type );
4275 furn_set( point( 23, i ), f_null );
4276 i_clear( tripoint( 23, i, get_abs_sub().z ) );
4277
4278 ter_set( point( i, 23 ), bw_type );
4279 furn_set( point( i, 23 ), f_null );
4280 i_clear( tripoint( i, 23, get_abs_sub().z ) );
4281
4282 if( lw == 2 ) {
4283 ter_set( point( 0, i ), lw_type );
4284 furn_set( point( 0, i ), f_null );
4285 i_clear( tripoint( 0, i, get_abs_sub().z ) );
4286 }
4287 if( tw == 2 ) {
4288 ter_set( point( i, 0 ), tw_type );
4289 furn_set( point( i, 0 ), f_null );
4290 i_clear( tripoint( i, 0, get_abs_sub().z ) );
4291 }
4292 }
4293 if( rw != 2 ) {
4294 ter_set( point( 23, 11 ), t_door_metal_c );
4295 ter_set( point( 23, 12 ), t_door_metal_c );
4296 }
4297 if( bw != 2 ) {
4298 ter_set( point( 11, 23 ), t_door_metal_c );
4299 ter_set( point( 12, 23 ), t_door_metal_c );
4300 }
4301 }
4302 } else { // then no json maps for lab_finale_1level were found
4303 // Start by setting up a large, empty room.
4304 for( int i = 0; i < SEEX * 2; i++ ) {
4305 for( int j = 0; j < SEEY * 2; j++ ) {
4306 if( i < lw || i > EAST_EDGE - rw ) {
4307 ter_set( point( i, j ), t_concrete_wall );
4308 } else if( j < tw || j > SOUTH_EDGE - bw ) {
4309 ter_set( point( i, j ), t_concrete_wall );
4310 } else {
4311 ter_set( point( i, j ), t_thconc_floor );
4312 }
4313 }
4314 }
4315 if( rw == 1 ) {
4318 }
4319 if( bw == 1 ) {
4322 }
4323
4324 int loot_variant; //only used for weapons testing variant.
4325 computer *tmpcomp = nullptr;
4326 switch( rng( 1, 5 ) ) {
4327 // Weapons testing - twice as common because it has 4 variants.
4328 case 1:
4329 case 2:
4330 loot_variant = rng( 1, 100 ); //The variants have a 67/22/7/4 split.
4331 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4332 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4333 point( SEEX * 2 - 7, 6 ), 1, true );
4334 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4335 point( 6, SEEY * 2 - 7 ), 1, true );
4336 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4337 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4338 spawn_item( point( SEEX - 4, SEEY - 2 ), "id_science" );
4339 if( loot_variant <= 96 ) {
4340 mtrap_set( this, point( SEEX - 3, SEEY - 3 ), tr_dissector );
4341 mtrap_set( this, point( SEEX + 2, SEEY - 3 ), tr_dissector );
4342 mtrap_set( this, point( SEEX - 3, SEEY + 2 ), tr_dissector );
4343 mtrap_set( this, point( SEEX + 2, SEEY + 2 ), tr_dissector );
4344 line( this, t_reinforced_glass, point( SEEX + 1, SEEY + 1 ), point( SEEX - 2, SEEY + 1 ) );
4345 line( this, t_reinforced_glass, point( SEEX - 2, SEEY ), point( SEEX - 2, SEEY - 2 ) );
4346 line( this, t_reinforced_glass, point( SEEX - 1, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4347 ter_set( point( SEEX + 1, SEEY - 1 ), t_reinforced_glass );
4349 furn_set( point( SEEX - 1, SEEY - 1 ), f_table );
4350 furn_set( point( SEEX, SEEY - 1 ), f_table );
4351 furn_set( point( SEEX - 1, SEEY ), f_table );
4352 furn_set( point( SEEX, SEEY ), f_table );
4353 if( loot_variant <= 67 ) {
4354 spawn_item( point( SEEX, SEEY - 1 ), "UPS_off" );
4355 spawn_item( point( SEEX, SEEY - 1 ), "heavy_battery_cell" );
4356 spawn_item( point( SEEX - 1, SEEY ), "v29" );
4357 spawn_item( point( SEEX - 1, SEEY ), "laser_rifle", dice( 1, 0 ) );
4358 spawn_item( point( SEEX, SEEY ), "plasma_gun" );
4359 spawn_item( point( SEEX, SEEY ), "plasma" );
4360 spawn_item( point( SEEX - 1, SEEY ), "recipe_atomic_battery" );
4361 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4362 } else if( loot_variant < 89 ) {
4363 spawn_item( point( SEEX - 1, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4364 spawn_item( point( SEEX, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4365 spawn_item( point( SEEX - 1, SEEY ), "mininuke", dice( 3, 6 ) );
4366 spawn_item( point( SEEX, SEEY ), "mininuke", dice( 3, 6 ) );
4367 spawn_item( point( SEEX, SEEY ), "recipe_atomic_battery" );
4368 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4369 } else { // loot_variant between 90 and 96.
4370 spawn_item( point( SEEX - 1, SEEY - 1 ), "rm13_armor" );
4371 spawn_item( point( SEEX, SEEY - 1 ), "plut_cell" );
4372 spawn_item( point( SEEX - 1, SEEY ), "plut_cell" );
4373 spawn_item( point( SEEX, SEEY ), "recipe_caseless" );
4374 }
4375 } else { // 4% of the lab ends will be this weapons testing end.
4376 mtrap_set( this, point( SEEX - 4, SEEY - 3 ), tr_dissector );
4377 mtrap_set( this, point( SEEX + 3, SEEY - 3 ), tr_dissector );
4378 mtrap_set( this, point( SEEX - 4, SEEY + 2 ), tr_dissector );
4379 mtrap_set( this, point( SEEX + 3, SEEY + 2 ), tr_dissector );
4380
4381 furn_set( point( SEEX - 2, SEEY - 1 ), f_rack );
4382 furn_set( point( SEEX - 1, SEEY - 1 ), f_rack );
4383 furn_set( point( SEEX, SEEY - 1 ), f_rack );
4384 furn_set( point( SEEX + 1, SEEY - 1 ), f_rack );
4385 furn_set( point( SEEX - 2, SEEY ), f_rack );
4386 furn_set( point( SEEX - 1, SEEY ), f_rack );
4387 furn_set( point( SEEX, SEEY ), f_rack );
4388 furn_set( point( SEEX + 1, SEEY ), f_rack );
4389 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY - 2 ),
4390 point( SEEX + 1, SEEY - 2 ) );
4391 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY + 1 ),
4392 point( SEEX + 1, SEEY + 1 ) );
4393 line( this, t_reinforced_glass, point( SEEX - 3, SEEY - 2 ), point( SEEX - 3, SEEY + 1 ) );
4394 line( this, t_reinforced_glass, point( SEEX + 2, SEEY - 2 ), point( SEEX + 2, SEEY + 1 ) );
4395 place_items( item_group_id( "ammo_rare" ), 96, point( SEEX - 2, SEEY - 1 ),
4396 point( SEEX + 1, SEEY - 1 ), false, calendar::start_of_cataclysm );
4397 place_items( item_group_id( "guns_rare" ), 96, point( SEEX - 2, SEEY ), point( SEEX + 1, SEEY ),
4398 false,
4400 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 1, 10 ) );
4401 }
4402 break;
4403 // Netherworld access
4404 case 3: {
4405 bool monsters_end = false;
4406 if( !one_in( 4 ) ) { // Trapped netherworld monsters
4407 monsters_end = true;
4408 tw = rng( SEEY + 3, SEEY + 5 );
4409 bw = tw + 4;
4410 lw = rng( SEEX - 6, SEEX - 2 );
4411 rw = lw + 6;
4412 for( int i = lw; i <= rw; i++ ) {
4413 for( int j = tw; j <= bw; j++ ) {
4414 if( j == tw || j == bw ) {
4415 if( ( i - lw ) % 2 == 0 ) {
4416 ter_set( point( i, j ), t_concrete_wall );
4417 } else {
4418 ter_set( point( i, j ), t_reinforced_glass );
4419 }
4420 } else if( ( i - lw ) % 2 == 0 ) {
4421 ter_set( point( i, j ), t_concrete_wall );
4422 } else if( j == tw + 2 ) {
4423 ter_set( point( i, j ), t_concrete_wall );
4424 } else { // Empty space holds monsters!
4425 place_spawns( GROUP_NETHER, 1, point( i, j ), point( i, j ), 1, true );
4426 }
4427 }
4428 }
4429 }
4430
4431 spawn_item( point( SEEX - 1, 8 ), "id_science" );
4432 tmpcomp = add_computer( tripoint( SEEX, 8, abs_sub.z ),
4433 _( "Sub-prime contact console" ), 7 );
4434 if( monsters_end ) { //only add these options when there are monsters.
4435 tmpcomp->add_option( _( "Terminate Specimens" ), COMPACT_TERMINATE, 2 );
4436 tmpcomp->add_option( _( "Release Specimens" ), COMPACT_RELEASE, 3 );
4437 }
4438 tmpcomp->add_option( _( "Toggle Portal" ), COMPACT_PORTAL, 8 );
4439 tmpcomp->add_option( _( "Activate Resonance Cascade" ), COMPACT_CASCADE, 10 );
4440 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4441 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4442 tmpcomp->set_access_denied_msg(
4443 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4444 ter_set( point( SEEX - 2, 4 ), t_radio_tower );
4445 ter_set( point( SEEX + 1, 4 ), t_radio_tower );
4446 ter_set( point( SEEX - 2, 7 ), t_radio_tower );
4447 ter_set( point( SEEX + 1, 7 ), t_radio_tower );
4448 }
4449 break;
4450
4451 // Bionics
4452 case 4: {
4453 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4454 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4455 point( SEEX * 2 - 7, 6 ), 1, true );
4456 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4457 point( 6, SEEY * 2 - 7 ), 1, true );
4458 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4459 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4460 mtrap_set( this, point( SEEX - 2, SEEY - 2 ), tr_dissector );
4461 mtrap_set( this, point( SEEX + 1, SEEY - 2 ), tr_dissector );
4462 mtrap_set( this, point( SEEX - 2, SEEY + 1 ), tr_dissector );
4463 mtrap_set( this, point( SEEX + 1, SEEY + 1 ), tr_dissector );
4464 square_furn( this, f_counter, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEY ) );
4465 int item_count = 0;
4466 while( item_count < 5 ) {
4467 item_count += place_items( item_group_id( "bionics" ), 75, point( SEEX - 1, SEEY - 1 ),
4468 point( SEEX, SEEY ), false, calendar::start_of_cataclysm ).size();
4469 }
4470 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4471 line( this, t_reinforced_glass, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) );
4472 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 1 ), point( SEEX - 2, SEEY ) );
4473 line( this, t_reinforced_glass, point( SEEX + 1, SEEY - 1 ), point( SEEX + 1, SEEY ) );
4474 spawn_item( point( SEEX - 4, SEEY - 3 ), "id_science" );
4475 ter_set( point( SEEX - 3, SEEY - 3 ), t_console );
4476 tmpcomp = add_computer( tripoint( SEEX - 3, SEEY - 3, abs_sub.z ),
4477 _( "Bionic access" ), 3 );
4478 tmpcomp->add_option( _( "Manifest" ), COMPACT_LIST_BIONICS, 0 );
4479 tmpcomp->add_option( _( "Open Chambers" ), COMPACT_RELEASE, 5 );
4480 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4481 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4482 tmpcomp->set_access_denied_msg(
4483 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4484 }
4485 break;
4486
4487 // CVD Forge
4488 case 5:
4489 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4490 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4491 point( SEEX * 2 - 7, 6 ), 1, true );
4492 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4493 point( 6, SEEY * 2 - 7 ), 1, true );
4494 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4495 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4496 line( this, t_cvdbody, point( SEEX - 2, SEEY - 2 ), point( SEEX - 2, SEEY + 1 ) );
4497 line( this, t_cvdbody, point( SEEX - 1, SEEY - 2 ), point( SEEX - 1, SEEY + 1 ) );
4498 line( this, t_cvdbody, point( SEEX, SEEY - 1 ), point( SEEX, SEEY + 1 ) );
4499 line( this, t_cvdbody, point( SEEX + 1, SEEY - 2 ), point( SEEX + 1, SEEY + 1 ) );
4500 ter_set( point( SEEX, SEEY - 2 ), t_cvdmachine );
4501 spawn_item( point( SEEX, SEEY - 3 ), "id_science" );
4502 break;
4503 }
4504 } // end use_hardcoded_lab_finale
4505
4506 // Handle stairs in the unlikely case they are needed.
4507
4508 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
4509 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
4510 const auto predicate = [this]( const tripoint & p ) {
4511 return ter( p ) == t_thconc_floor && furn( p ) == f_null &&
4512 tr_at( p ).is_null();
4513 };
4514 const auto range = points_in_rectangle( { 0, 0, abs_sub.z },
4515 { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
4516 if( const auto p = random_point( range, predicate ) ) {
4517 ter_set( *p, t_stair_type );
4518 }
4519 }
4520 };
4521 maybe_insert_stairs( dat.above(), t_stairs_up );
4522 maybe_insert_stairs( terrain_type, t_stairs_down );
4523
4524 int light_odds = 0;
4525 // central labs are always fully lit, other labs have half chance of some lights.
4526 if( central_lab ) {
4527 light_odds = 1;
4528 } else if( one_in( 2 ) ) {
4529 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4530 }
4531 if( light_odds > 0 ) {
4532 for( int i = 0; i < SEEX * 2; i++ ) {
4533 for( int j = 0; j < SEEY * 2; j++ ) {
4534 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4535 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4537 }
4538 }
4539 }
4540 }
4541 }
4542 }
4543}
void set_access_denied_msg(const std::string &new_msg)
Definition: computer.cpp:97
void add_failure(const computer_failure &failure)
Definition: computer.cpp:87
void add_option(const computer_option &opt)
Definition: computer.cpp:76
void set_temperature(const tripoint &p, int temperature)
Definition: map.cpp:4177
computer * add_computer(const tripoint &p, const std::string &name, int security)
Definition: mapgen.cpp:5816
void i_clear(const tripoint &p)
Definition: map.cpp:4225
std::vector< item * > place_items(const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
Place items from item group in the rectangle f - t.
Definition: mapgen.cpp:5546
void trap_set(const tripoint &p, const trap_id &type)
Definition: map.cpp:5287
bool generate(mapgendata &dat, const std::string &key, const int hardcoded_weight=0) const
Definition: mapgen.cpp:346
int zlevel() const
Definition: mapgendata.h:99
@ COMPACT_RELEASE
Definition: computer.h:42
@ COMPACT_TERMINATE
Definition: computer.h:59
@ COMPACT_PORTAL
Definition: computer.h:40
@ COMPACT_CASCADE
Definition: computer.h:19
@ COMPACT_LIST_BIONICS
Definition: computer.h:32
@ COMPFAIL_SECUBOTS
Definition: computer.h:77
@ COMPFAIL_MANHACKS
Definition: computer.h:74
void draw_rough_circle(std::function< void(point)>set, point p, int rad)
field_type_id fd_gas_vent
Definition: field_type.cpp:350
field_type_id fd_smoke_vent
Definition: field_type.cpp:385
ter_id t_door_glass_frosted_c
Definition: mapdata.cpp:666
ter_id t_cvdmachine
Definition: mapdata.cpp:714
ter_id t_slime
Definition: mapdata.cpp:639
ter_id t_strconc_floor
Definition: mapdata.cpp:633
furn_id f_table
Definition: mapdata.cpp:1106
furn_id f_fungal_clump
Definition: mapdata.cpp:1118
ter_id t_cvdbody
Definition: mapdata.cpp:714
ter_id t_radio_tower
Definition: mapdata.cpp:705
ter_id t_fungus_floor_in
Definition: mapdata.cpp:692
furn_id f_counter
Definition: mapdata.cpp:1107
furn_id f_rack
Definition: mapdata.cpp:1109
ter_id t_fungus_wall
Definition: mapdata.cpp:692
ter_id t_reinforced_glass
Definition: mapdata.cpp:652
ter_id t_concrete_wall
Definition: mapdata.cpp:648
ter_id t_floor
Definition: mapdata.cpp:634
ter_id t_thconc_floor_olight
Definition: mapdata.cpp:633
ter_id t_bars
Definition: mapdata.cpp:655
ter_id t_thconc_floor
Definition: mapdata.cpp:633
furn_id f_rubble_rock
Definition: mapdata.cpp:1099
ter_id t_stairs_up
Definition: mapdata.cpp:720
ter_id t_stairs_down
Definition: mapdata.cpp:720
ter_id t_marloss
Definition: mapdata.cpp:692
ter_id t_door_metal_locked
Definition: mapdata.cpp:664
ter_id t_card_science
Definition: mapdata.cpp:724
ter_id t_reinforced_door_glass_c
Definition: mapdata.cpp:654
furn_id f_flower_fungal
Definition: mapdata.cpp:1118
static const mongroup_id GROUP_ROBOT_SECUBOT("GROUP_ROBOT_SECUBOT")
void square_furn(map *m, const furn_id &type, point p1, point p2)
Definition: mapgen.cpp:6505
static const mongroup_id GROUP_HAZMATBOT("GROUP_HAZMATBOT")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static const mongroup_id GROUP_TURRET("GROUP_TURRET")
void line(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6485
const int SOUTH_EDGE
Definition: mapgen.cpp:2953
static void science_room(map *m, point p1, point p2, int z, int rotate)
Definition: mapgen.cpp:5982
const int EAST_EDGE
Definition: mapgen.cpp:2954
static mapgen_factory oter_mapgen
Definition: mapgen.cpp:355
static const mongroup_id GROUP_FUNGI_FUNGALOID("GROUP_FUNGI_FUNGALOID")
static const mongroup_id GROUP_LAB("GROUP_LAB")
static const trap_str_id tr_portal("tr_portal")
static const trap_str_id tr_dissector("tr_dissector")
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
std::pair< item, int > item_count
Definition: pickup.cpp:64
int dice(int number, int sides)
Definition: rng.cpp:85
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References _, mapgendata::above(), abs_sub, add_computer(), computer::add_failure(), add_field(), add_item_or_charges(), computer::add_option(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_GLOWING, ARTPROP_SCALED, ARTPROP_WARM, ARTPROP_WHISPERING, center, item::charges, COMPACT_CASCADE, COMPACT_LIST_BIONICS, COMPACT_PORTAL, COMPACT_RELEASE, COMPACT_TERMINATE, COMPFAIL_MANHACKS, COMPFAIL_SECUBOTS, connects_to(), contains, create_anomaly(), debugmsg, destroy(), dice(), draw_circle(), draw_rough_circle(), mapgendata::east(), EAST_EDGE, f_counter, f_flower_fungal, f_fungal_clump, f_null, f_rack, f_rubble_rock, f_table, fd_gas_vent, fd_smoke_vent, furn(), furn_set(), mapgen_factory::generate(), get_abs_sub(), GROUP_FUNGI_FUNGALOID, GROUP_HAZMATBOT, GROUP_LAB, GROUP_NETHER, GROUP_ROBOT_SECUBOT, GROUP_TURRET, has_flag(), has_flag_furn(), has_flag_ter(), i_clear(), trap::is_null(), is_ot_match(), line(), make_rubble(), mtrap_set(), mapgendata::north(), one_in(), oter_mapgen, place_items(), place_spawns(), point_west, point_zero, points_in_rectangle(), prefix, random_entry(), random_point(), rng(), rotate(), science_room(), SEEX, SEEY, computer::set_access_denied_msg(), set_radiation(), set_temperature(), mapgendata::south(), SOUTH_EDGE, spawn_item(), square_furn(), calendar::start_of_cataclysm, t_bars, t_card_science, t_concrete_wall, t_console, t_cvdbody, t_cvdmachine, t_dirt, t_door_glass_frosted_c, t_door_metal_c, t_door_metal_locked, t_floor, t_fungus_floor_in, t_fungus_wall, t_marloss, t_radio_tower, t_reinforced_door_glass_c, t_reinforced_glass, t_rock_floor, t_sewage, t_slime, t_stairs_down, t_stairs_up, t_strconc_floor, t_thconc_floor, t_thconc_floor_olight, t_water_sh, ter(), ter_set(), terrain, mapgendata::terrain_type(), tr_at(), tr_dissector, tr_portal, trap_set(), type, mapgendata::west(), tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_line_furn()

void map::draw_line_furn ( const furn_id type,
point  p1,
point  p2 
)

Definition at line 8474 of file map.cpp.

8475{
8476 draw_line( [this, type]( point p ) {
8477 this->furn_set( p, type );
8478 }, p1, p2 );
8479}
void draw_line(std::function< void(point)>set, point p1, point p2)

References draw_line(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), and line_furn().

◆ draw_line_ter()

void map::draw_line_ter ( const ter_id type,
point  p1,
point  p2 
)

Definition at line 8467 of file map.cpp.

8468{
8469 draw_line( [this, type]( point p ) {
8470 this->ter_set( p, type );
8471 }, p1, p2 );
8472}

References draw_line(), ter_set(), and type.

Referenced by jmapgen_setmap::apply(), and line().

◆ draw_map()

void map::draw_map ( mapgendata dat)
protected

Definition at line 2913 of file mapgen.cpp.

2914{
2915 const oter_id &terrain_type = dat.terrain_type();
2916 const std::string function_key = terrain_type->get_mapgen_id();
2917 bool found = true;
2918
2919 const bool generated = run_mapgen_func( function_key, dat );
2920
2921 if( !generated ) {
2922 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ||
2923 is_ot_match( "slime_pit", terrain_type, ot_match_type::prefix ) ) {
2924 draw_slimepit( dat );
2925 } else if( is_ot_match( "triffid", terrain_type, ot_match_type::prefix ) ) {
2926 draw_triffid( dat );
2927 } else if( is_ot_match( "office", terrain_type, ot_match_type::prefix ) ) {
2928 draw_office_tower( dat );
2929 } else if( is_ot_match( "temple", terrain_type, ot_match_type::prefix ) ) {
2930 draw_temple( dat );
2931 } else if( is_ot_match( "mine", terrain_type, ot_match_type::prefix ) ) {
2932 draw_mine( dat );
2933 } else if( is_ot_match( "anthill", terrain_type, ot_match_type::contains ) ) {
2934 draw_anthill( dat );
2935 } else if( is_ot_match( "lab", terrain_type, ot_match_type::contains ) ) {
2936 draw_lab( dat );
2937 } else {
2938 found = false;
2939 }
2940 }
2941
2942 if( !found ) {
2943 // not one of the hardcoded ones!
2944 // load from JSON???
2945 debugmsg( "Error: tried to generate map for omtype %s, \"%s\" (id_mapgen %s)",
2946 terrain_type.id().c_str(), terrain_type->get_name(), function_key.c_str() );
2947 fill_background( this, t_floor );
2948 }
2949
2950 draw_connections( dat );
2951}
void draw_office_tower(mapgendata &dat)
Definition: mapgen.cpp:2956
void draw_mine(mapgendata &dat)
Definition: mapgen.cpp:4791
void draw_triffid(mapgendata &dat)
Definition: mapgen.cpp:5121
void draw_anthill(mapgendata &dat)
Definition: mapgen.cpp:5059
void draw_slimepit(mapgendata &dat)
Definition: mapgen.cpp:5077
void draw_lab(mapgendata &dat)
Definition: mapgen.cpp:3544
void draw_connections(mapgendata &dat)
Definition: mapgen.cpp:5269
void draw_temple(mapgendata &dat)
Definition: mapgen.cpp:4545
void fill_background(map *m, const ter_id &type)
Definition: mapgen.cpp:6493
bool run_mapgen_func(const std::string &mapgen_id, mapgendata &dat)
Definition: mapgen.cpp:6717
std::string get_name() const
Definition: omdata.h:205
std::string get_mapgen_id() const
Definition: overmap.cpp:798

References string_id< T >::c_str(), contains, debugmsg, draw_anthill(), draw_connections(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), fill_background(), oter_t::get_mapgen_id(), oter_t::get_name(), int_id< T >::id(), is_ot_match(), prefix, run_mapgen_func(), t_floor, and mapgendata::terrain_type().

Referenced by generate().

◆ draw_maptile()

bool map::draw_maptile ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Internal version of the drawsq.

Keeps a cached maptile for less re-getting. Returns false if it has drawn all it should, true if draw_from_above should be called after.

Definition at line 5975 of file map.cpp.

5977{
5978 drawsq_params param = params;
5979 nc_color tercol;
5980 const ter_t &curr_ter = curr_maptile.get_ter_t();
5981 const furn_t &curr_furn = curr_maptile.get_furn_t();
5982 const trap &curr_trap = curr_maptile.get_trap().obj();
5983 const field &curr_field = curr_maptile.get_field();
5984 int sym;
5985 bool hi = false;
5986 bool graf = false;
5987 bool draw_item_sym = false;
5988
5989 int terrain_sym;
5990 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
5991 terrain_sym = determine_wall_corner( p );
5992 } else {
5993 terrain_sym = curr_ter.symbol();
5994 }
5995
5996 if( curr_furn.id ) {
5997 sym = curr_furn.symbol();
5998 tercol = curr_furn.color();
5999 } else {
6000 sym = terrain_sym;
6001 tercol = curr_ter.color();
6002 }
6003 if( curr_ter.has_flag( TFLAG_SWIMMABLE ) && curr_ter.has_flag( TFLAG_DEEP_WATER ) &&
6004 !g->u.is_underwater() ) {
6005 param.show_items( false ); // Can only see underwater items if WE are underwater
6006 }
6007 // If there's a trap here, and we have sufficient perception, draw that instead
6008 if( curr_trap.can_see( p, g->u ) ) {
6009 tercol = curr_trap.color;
6010 if( curr_trap.sym == '%' ) {
6011 switch( rng( 1, 5 ) ) {
6012 case 1:
6013 sym = '*';
6014 break;
6015 case 2:
6016 sym = '0';
6017 break;
6018 case 3:
6019 sym = '8';
6020 break;
6021 case 4:
6022 sym = '&';
6023 break;
6024 case 5:
6025 sym = '+';
6026 break;
6027 }
6028 } else {
6029 sym = curr_trap.sym;
6030 }
6031 }
6032 if( curr_field.field_count() > 0 ) {
6033 const field_type_id &fid = curr_field.displayed_field_type();
6034 const field_entry *fe = curr_field.find_field( fid );
6035 const auto field_symbol = fid->get_symbol();
6036 if( field_symbol == "&" || fe == nullptr ) {
6037 // Do nothing, a '&' indicates invisible fields.
6038 } else if( field_symbol == "*" ) {
6039 // A random symbol.
6040 switch( rng( 1, 5 ) ) {
6041 case 1:
6042 sym = '*';
6043 break;
6044 case 2:
6045 sym = '0';
6046 break;
6047 case 3:
6048 sym = '8';
6049 break;
6050 case 4:
6051 sym = '&';
6052 break;
6053 case 5:
6054 sym = '+';
6055 break;
6056 }
6057 } else {
6058 // A field symbol '%' indicates the field should not hide
6059 // items/terrain. When the symbol is not '%' it will
6060 // hide items (the color is still inverted if there are items,
6061 // but the tile symbol is not changed).
6062 // draw_item_sym indicates that the item symbol should be used
6063 // even if sym is not '.'.
6064 // As we don't know at this stage if there are any items
6065 // (that are visible to the player!), we always set the symbol.
6066 // If there are items and the field does not hide them,
6067 // the code handling items will override it.
6068 draw_item_sym = ( field_symbol == "'%" );
6069 // If field display_priority is > 1, and the field is set to hide items,
6070 //draw the field as it obscures what's under it.
6071 if( ( field_symbol != "%" && fid.obj().priority > 1 ) || ( field_symbol != "%" &&
6072 sym == '.' ) ) {
6073 // default terrain '.' and
6074 // non-default field symbol -> field symbol overrides terrain
6075 sym = field_symbol[0];
6076 }
6077 tercol = fe->color();
6078 }
6079 }
6080
6081 // TODO: change the local variable sym to std::string and use it instead of this hack.
6082 // Currently this are different variables because terrain/... uses int as symbol type and
6083 // item now use string. Ideally they should all be strings.
6084 std::string item_sym;
6085
6086 // If there are items here, draw those instead
6087 if( param.show_items() && curr_maptile.get_item_count() > 0 && sees_some_items( p, g->u ) ) {
6088 // if there's furniture/terrain/trap/fields (sym!='.')
6089 // and we should not override it, then only highlight the square
6090 if( sym != '.' && sym != '%' && !draw_item_sym ) {
6091 hi = true;
6092 } else {
6093 // otherwise override with the symbol of the last item
6094 item_sym = curr_maptile.get_uppermost_item().symbol();
6095 if( !draw_item_sym ) {
6096 tercol = curr_maptile.get_uppermost_item().color();
6097 }
6098 if( curr_maptile.get_item_count() > 1 ) {
6099 param.highlight( !param.highlight() );
6100 }
6101 }
6102 }
6103
6104 int memory_sym = sym;
6105 int veh_part = 0;
6106 const vehicle *veh = veh_at_internal( p, veh_part );
6107 if( veh != nullptr ) {
6108 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( veh_part ) ) );
6109 tercol = veh->part_color( veh_part );
6110 item_sym.clear(); // clear the item symbol so `sym` is used instead.
6111
6112 if( !veh->forward_velocity() && !veh->player_in_control( g->u ) ) {
6113 memory_sym = sym;
6114 }
6115 }
6116
6117 if( param.memorize() && check_and_set_seen_cache( p ) ) {
6118 g->u.memorize_symbol( getabs( p ), memory_sym );
6119 }
6120
6121 // If there's graffiti here, change background color
6122 if( curr_maptile.has_graffiti() ) {
6123 graf = true;
6124 }
6125
6126 const auto u_vision = g->u.get_vision_modes();
6127 if( u_vision[BOOMERED] ) {
6128 tercol = c_magenta;
6129 } else if( u_vision[NV_GOGGLES] ) {
6130 tercol = param.bright_light() ? c_white : c_light_green;
6131 } else if( param.low_light() ) {
6132 tercol = c_dark_gray;
6133 } else if( u_vision[DARKNESS] ) {
6134 tercol = c_dark_gray;
6135 }
6136
6137 if( param.highlight() ) {
6138 tercol = invert_color( tercol );
6139 } else if( hi ) {
6140 tercol = hilite( tercol );
6141 } else if( graf ) {
6142 tercol = red_background( tercol );
6143 }
6144
6145 if( item_sym.empty() && sym == ' ' ) {
6146 if( !zlevels || p.z <= -OVERMAP_DEPTH || !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6147 // Print filler symbol
6148 sym = ' ';
6149 tercol = c_black;
6150 } else {
6151 // Draw tile underneath this one instead
6152 return false;
6153 }
6154 }
6155
6156 if( params.output() ) {
6157 if( item_sym.empty() ) {
6158 wputch( w, tercol, sym );
6159 } else {
6160 wprintz( w, tercol, item_sym );
6161 }
6162 }
6163 return true;
6164}
nc_color color() const
Definition: field.cpp:94
field_entry * find_field(const field_type_id &field_type_to_find)
Returns a field entry corresponding to the field_type_id parameter passed in.
Definition: field.cpp:153
field_type_id displayed_field_type() const
Returns field type that should be drawn.
Definition: field.cpp:275
unsigned int field_count() const
Definition: field.cpp:246
bool check_and_set_seen_cache(const tripoint &p) const
Definition: map.cpp:8929
bool sees_some_items(const tripoint &p, const Creature &who) const
Check if creature can see some items at p.
Definition: map.cpp:4833
nc_color part_color(int p, bool exact=false) const
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:278
float forward_velocity() const
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color hilite(const nc_color &c)
Definition: color.cpp:509
@ TFLAG_SWIMMABLE
Definition: mapdata.h:279
void wprintz(const catacurses::window &w, const nc_color &FG, const std::string &text)
Definition: output.cpp:2089
constexpr drawsq_params & show_items(bool v)
Whether to draw items on the tile.
Definition: map.h:212
int priority
Definition: field_type.h:176
std::string get_symbol(int level=0) const
Definition: field_type.h:195
furn_str_id id
Definition: mapdata.h:500
nc_color color
Definition: trap.h:93
int sym
Definition: trap.h:92

References BOOMERED, drawsq_params::bright_light(), c_black, c_dark_gray, c_light_green, c_magenta, c_white, trap::can_see(), check_and_set_seen_cache(), field_entry::color(), item::color(), map_data_common_t::color(), trap::color, DARKNESS, determine_wall_corner(), tileray::dir_symbol(), field::displayed_field_type(), vehicle::face, field::field_count(), field::find_field(), vehicle::forward_velocity(), g, maptile::get_field(), maptile::get_furn_t(), maptile::get_item_count(), field_type::get_symbol(), maptile::get_ter_t(), maptile::get_trap(), maptile::get_uppermost_item(), getabs(), map_data_common_t::has_flag(), maptile::has_graffiti(), drawsq_params::highlight(), hilite(), furn_t::id, invert_color(), drawsq_params::low_light(), drawsq_params::memorize(), NV_GOGGLES, int_id< T >::obj(), drawsq_params::output(), OVERMAP_DEPTH, vehicle::part_color(), vehicle::part_sym(), vehicle::player_in_control(), field_type::priority, red_background(), rng(), sees_some_items(), drawsq_params::show_items(), special_symbol(), trap::sym, item::symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, TFLAG_SWIMMABLE, veh_at_internal(), wprintz(), wputch(), tripoint::z, and zlevels.

Referenced by draw(), and drawsq().

◆ draw_mine()

void map::draw_mine ( mapgendata dat)
protected

Definition at line 4791 of file mapgen.cpp.

4792{
4793 const oter_id &terrain_type = dat.terrain_type();
4794 if( terrain_type == "mine" || terrain_type == "mine_down" ) {
4795 if( is_ot_match( "mine", dat.north(), ot_match_type::prefix ) ) {
4796 dat.n_fac = ( one_in( 10 ) ? 0 : -2 );
4797 } else {
4798 dat.n_fac = 4;
4799 }
4800 if( is_ot_match( "mine", dat.east(), ot_match_type::prefix ) ) {
4801 dat.e_fac = ( one_in( 10 ) ? 0 : -2 );
4802 } else {
4803 dat.e_fac = 4;
4804 }
4805 if( is_ot_match( "mine", dat.south(), ot_match_type::prefix ) ) {
4806 dat.s_fac = ( one_in( 10 ) ? 0 : -2 );
4807 } else {
4808 dat.s_fac = 4;
4809 }
4810 if( is_ot_match( "mine", dat.west(), ot_match_type::prefix ) ) {
4811 dat.w_fac = ( one_in( 10 ) ? 0 : -2 );
4812 } else {
4813 dat.w_fac = 4;
4814 }
4815
4816 for( int i = 0; i < SEEX * 2; i++ ) {
4817 for( int j = 0; j < SEEY * 2; j++ ) {
4818 if( i >= dat.w_fac + rng( 0, 2 ) && i <= EAST_EDGE - dat.e_fac - rng( 0, 2 ) &&
4819 j >= dat.n_fac + rng( 0, 2 ) && j <= SOUTH_EDGE - dat.s_fac - rng( 0, 2 ) &&
4820 i + j >= 4 && ( SEEX * 2 - i ) + ( SEEY * 2 - j ) >= 6 ) {
4821 ter_set( point( i, j ), t_rock_floor );
4822 } else {
4823 ter_set( point( i, j ), t_rock );
4824 }
4825 }
4826 }
4827
4828 // Not an entrance; maybe some hazards!
4829 switch( rng( 0, 4 ) ) {
4830 case 0:
4831 break; // Nothing! Lucky!
4832
4833 case 1: {
4834 // Toxic gas
4835 point gas_vent_location( rng( 9, 14 ), rng( 9, 14 ) );
4836 ter_set( point( gas_vent_location ), t_rock );
4837 add_field( { gas_vent_location, abs_sub.z }, fd_gas_vent, 2 );
4838 }
4839 break;
4840
4841 case 2: {
4842 // Lava
4843 point start_location( rng( 6, SEEX ), rng( 6, SEEY ) );
4844 point end_location( rng( SEEX + 1, SEEX * 2 - 7 ), rng( SEEY + 1, SEEY * 2 - 7 ) );
4845 const int num = rng( 2, 4 );
4846 for( int i = 0; i < num; i++ ) {
4847 int lx1 = start_location.x + rng( -1, 1 );
4848 int lx2 = end_location.x + rng( -1, 1 );
4849 int ly1 = start_location.y + rng( -1, 1 );
4850 int ly2 = end_location.y + rng( -1, 1 );
4851 line( this, t_lava, point( lx1, ly1 ), point( lx2, ly2 ) );
4852 }
4854 tripoint( end_location,
4855 abs_sub.z ) ) ) {
4856 if( ter( ore ) == t_rock_floor && one_in( 10 ) ) {
4857 spawn_item( ore, "chunk_sulfur" );
4858 }
4859 }
4860 }
4861 break;
4862
4863 case 3: {
4864 // Wrecked equipment
4865 point wreck_location( rng( 9, 14 ), rng( 9, 14 ) );
4866 for( int i = wreck_location.x - 3; i < wreck_location.x + 3; i++ ) {
4867 for( int j = wreck_location.y - 3; j < wreck_location.y + 3; j++ ) {
4868 if( !one_in( 4 ) ) {
4870 }
4871 }
4872 }
4873 }
4874 break;
4875
4876 case 4: {
4877 // Dead miners
4878 const int num_bodies = rng( 4, 8 );
4879 for( int i = 0; i < num_bodies; i++ ) {
4880 if( const auto body = random_point( *this, [this]( const tripoint & p ) {
4881 return move_cost( p ) == 2;
4882 } ) ) {
4883 add_item( *body, item::make_corpse() );
4884 place_items( item_group_id( "mon_zombie_miner_death_drops" ), 100, *body, *body,
4886 }
4887 }
4888 }
4889 break;
4890
4891 }
4892
4893 if( terrain_type == "mine_down" ) { // Don't forget to build a slope down!
4894 std::vector<direction> open;
4895 if( dat.n_fac == 4 ) {
4896 open.push_back( direction::NORTH );
4897 }
4898 if( dat.e_fac == 4 ) {
4899 open.push_back( direction::EAST );
4900 }
4901 if( dat.s_fac == 4 ) {
4902 open.push_back( direction::SOUTH );
4903 }
4904 if( dat.w_fac == 4 ) {
4905 open.push_back( direction::WEST );
4906 }
4907
4908 if( open.empty() ) { // We'll have to build it in the center
4909 int tries = 0;
4910 point p;
4911 bool okay = true;
4912 do {
4913 p.x = rng( SEEX - 6, SEEX + 1 );
4914 p.y = rng( SEEY - 6, SEEY + 1 );
4915 okay = true;
4916 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4917 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4918 if( ter( point( i, j ) ) != t_rock_floor ) {
4919 okay = false;
4920 }
4921 }
4922 }
4923 if( !okay ) {
4924 tries++;
4925 }
4926 } while( !okay && tries < 10 );
4927 if( tries == 10 ) { // Clear the area around the slope down
4928 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4929 }
4930 // NOLINTNEXTLINE(cata-use-named-point-constants)
4931 square( this, t_slope_down, p + point( 1, 1 ), p + point( 2, 2 ) );
4932 } else { // We can build against a wall
4933 switch( random_entry( open ) ) {
4934 case direction::NORTH:
4935 square( this, t_rock_floor, point( SEEX - 3, 6 ), point( SEEX + 2, SEEY ) );
4936 line( this, t_slope_down, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4937 break;
4938 case direction::EAST:
4939 square( this, t_rock_floor, point( SEEX + 1, SEEY - 3 ), point( SEEX * 2 - 7, SEEY + 2 ) );
4940 line( this, t_slope_down, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4941 break;
4942 case direction::SOUTH:
4943 square( this, t_rock_floor, point( SEEX - 3, SEEY + 1 ), point( SEEX + 2, SEEY * 2 - 7 ) );
4944 line( this, t_slope_down, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4945 break;
4946 case direction::WEST:
4947 square( this, t_rock_floor, point( 6, SEEY - 3 ), point( SEEX, SEEY + 2 ) );
4948 line( this, t_slope_down, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4949 break;
4950 default:
4951 break;
4952 }
4953 }
4954 } // Done building a slope down
4955
4956 if( dat.above() == "mine_down" ) { // Don't forget to build a slope up!
4957 std::vector<direction> open;
4958 if( dat.n_fac == 6 && ter( point( SEEX, 6 ) ) != t_slope_down ) {
4959 open.push_back( direction::NORTH );
4960 }
4961 if( dat.e_fac == 6 && ter( point( SEEX * 2 - 7, SEEY ) ) != t_slope_down ) {
4962 open.push_back( direction::EAST );
4963 }
4964 if( dat.s_fac == 6 && ter( point( SEEX, SEEY * 2 - 7 ) ) != t_slope_down ) {
4965 open.push_back( direction::SOUTH );
4966 }
4967 if( dat.w_fac == 6 && ter( point( 6, SEEY ) ) != t_slope_down ) {
4968 open.push_back( direction::WEST );
4969 }
4970
4971 if( open.empty() ) { // We'll have to build it in the center
4972 int tries = 0;
4973 point p;
4974 bool okay = true;
4975 do {
4976 p.x = rng( SEEX - 6, SEEX + 1 );
4977 p.y = rng( SEEY - 6, SEEY + 1 );
4978 okay = true;
4979 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4980 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4981 if( ter( point( i, j ) ) != t_rock_floor ) {
4982 okay = false;
4983 }
4984 }
4985 }
4986 if( !okay ) {
4987 tries++;
4988 }
4989 } while( !okay && tries < 10 );
4990 if( tries == 10 ) { // Clear the area around the slope down
4991 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4992 }
4993 // NOLINTNEXTLINE(cata-use-named-point-constants)
4994 square( this, t_slope_up, p + point( 1, 1 ), p + point( 2, 2 ) );
4995
4996 } else { // We can build against a wall
4997 switch( random_entry( open ) ) {
4998 case direction::NORTH:
4999 line( this, t_slope_up, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
5000 break;
5001 case direction::EAST:
5002 line( this, t_slope_up, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
5003 break;
5004 case direction::SOUTH:
5005 line( this, t_slope_up, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
5006 break;
5007 case direction::WEST:
5008 line( this, t_slope_up, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
5009 break;
5010 default:
5011 break;
5012 }
5013 }
5014 } // Done building a slope up
5015 } else if( terrain_type == "mine_finale" ) {
5016 // Set up the basic chamber
5017 for( int i = 0; i < SEEX * 2; i++ ) {
5018 for( int j = 0; j < SEEY * 2; j++ ) {
5019 if( i > rng( 1, 3 ) && i < SEEX * 2 - rng( 2, 4 ) &&
5020 j > rng( 1, 3 ) && j < SEEY * 2 - rng( 2, 4 ) ) {
5021 ter_set( point( i, j ), t_rock_floor );
5022 } else {
5023 ter_set( point( i, j ), t_rock );
5024 }
5025 }
5026 }
5027
5028 // Now draw the entrance(s)
5029 if( dat.north() == "mine" ) {
5030 square( this, t_rock_floor, point( SEEX, 0 ), point( SEEX + 1, 3 ) );
5031 }
5032
5033 if( dat.east() == "mine" ) {
5034 square( this, t_rock_floor, point( SEEX * 2 - 4, SEEY ), point( EAST_EDGE, SEEY + 1 ) );
5035 }
5036
5037 if( dat.south() == "mine" ) {
5038 square( this, t_rock_floor, point( SEEX, SEEY * 2 - 4 ), point( SEEX + 1, SOUTH_EDGE ) );
5039 }
5040
5041 if( dat.west() == "mine" ) {
5042 square( this, t_rock_floor, point( 0, SEEY ), point( 3, SEEY + 1 ) );
5043 }
5044
5045 // Now, pick and generate a type of finale!
5046 // The Thing dog
5047 const int num_bodies = rng( 4, 8 );
5048 for( int i = 0; i < num_bodies; i++ ) {
5049 point p3( rng( 4, SEEX * 2 - 5 ), rng( 4, SEEX * 2 - 5 ) );
5050 add_item( p3, item::make_corpse() );
5051 place_items( item_group_id( "mon_zombie_miner_death_drops" ), 60, p3,
5052 p3, false, calendar::start_of_cataclysm );
5053 }
5054 place_spawns( GROUP_DOG_THING, 1, point( SEEX, SEEX ), point( SEEX + 1, SEEX + 1 ), 1, true, true );
5055 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( SEEY, SEEY + 1 ), abs_sub.z ) );
5056 }
5057}
void spawn_artifact(const tripoint &p)
Definition: map.cpp:4281
static void open()
furn_id f_wreckage
Definition: mapdata.cpp:1099
ter_id t_rock
Definition: mapdata.cpp:675
ter_id t_lava
Definition: mapdata.cpp:697
static const mongroup_id GROUP_DOG_THING("GROUP_DOG_THING")
void square(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6501

References mapgendata::above(), abs_sub, add_field(), add_item(), mapgendata::e_fac, EAST, mapgendata::east(), EAST_EDGE, f_wreckage, fd_gas_vent, GROUP_DOG_THING, is_ot_match(), line(), item::make_corpse(), make_rubble(), move_cost(), mapgendata::n_fac, NORTH, mapgendata::north(), num, one_in(), open(), place_items(), place_spawns(), points_in_rectangle(), prefix, random_entry(), random_point(), rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH, mapgendata::south(), SOUTH_EDGE, spawn_artifact(), spawn_item(), square(), calendar::start_of_cataclysm, t_lava, t_rock, t_rock_floor, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, WEST, mapgendata::west(), point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ draw_office_tower()

void map::draw_office_tower ( mapgendata dat)
protected

Definition at line 2956 of file mapgen.cpp.

2957{
2958 const oter_id &terrain_type = dat.terrain_type();
2959 const auto place_office_chairs = [&]() {
2960 int num_chairs = rng( 0, 6 );
2961 for( int i = 0; i < num_chairs; i++ ) {
2962 add_vehicle( vproto_id( "swivel_chair" ), point( rng( 6, 16 ), rng( 6, 16 ) ),
2963 0_degrees, -1, -1, false );
2964 }
2965 };
2966
2967 const auto ter_key = mapf::ter_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2968 "t + = D w T S e o h c d l s", t_elevator, t_stairs_down,
2976 const auto fur_key = mapf::furn_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2977 "t + = D w T S e o h c d l s", f_null, f_null, f_null,
2983 f_null );
2984 const auto b_ter_key = mapf::ter_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2985 "t + = D w T S e o h c d l", t_elevator, t_rock,
2993 t_floor, t_floor );
2994 const auto b_fur_key = mapf::furn_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2995 "t + = D w T S e o h c d l", f_null, f_null, f_null,
3002
3003 if( terrain_type == "office_tower_1_entrance" ) {
3004 dat.fill_groundcover();
3006 "ss%|....+...|...|EEED...\n"
3007 "ss%|----|...|...|EEx|...\n"
3008 "ss%Vcdc^|...|-+-|---|...\n"
3009 "ss%Vch..+...............\n"
3010 "ss%V....|...............\n"
3011 "ss%|----|-|-+--ccc--|...\n"
3012 "ss%|..C..C|.....h..r|-+-\n"
3013 "sss=......+..h.....r|...\n"
3014 "ss%|r..CC.|.ddd....r|T.S\n"
3015 "ss%|------|---------|---\n"
3016 "ss%|####################\n"
3017 "ss%|#|------||------|###\n"
3018 "ss%|#|......||......|###\n"
3019 "ss%|||......||......|###\n"
3020 "ss%||x......||......||##\n"
3021 "ss%|||......||......x|##\n"
3022 "ss%|#|......||......||##\n"
3023 "ss%|#|......||......|###\n"
3024 "ss%|#|XXXXXX||XXXXXX|###\n"
3025 "ss%|-|__,,__||__,,__|---\n"
3026 "ss%% x_,,,,_ __,,__ %%\n"
3027 "ss __,,__ _,,,,_ \n"
3028 "ssssss__,,__ss__,,__ssss\n"
3029 "ssssss______ss______ssss\n", ter_key, fur_key );
3030 place_items( item_group_id( "office" ), 75, point( 4, 2 ), point( 6, 2 ), false,
3032 place_items( item_group_id( "office" ), 75, point( 19, 6 ), point( 19, 6 ), false,
3034 place_items( item_group_id( "office" ), 75, point( 12, 8 ), point( 14, 8 ), false,
3036 if( dat.monster_density() > 1 ) {
3038 } else {
3039 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 1, true );
3040 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 0.15 );
3041 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3042 }
3043 place_office_chairs();
3044
3045 if( dat.north() == "office_tower_1" && dat.west() == "office_tower_1" ) {
3046 rotate( 3 );
3047 } else if( dat.north() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3048 rotate( 0 );
3049 } else if( dat.south() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3050 rotate( 1 );
3051 } else if( dat.west() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3052 rotate( 2 );
3053 }
3054 } else if( terrain_type == "office_tower_1" ) {
3055 // Init to grass & dirt;
3056 dat.fill_groundcover();
3057 if( ( dat.south() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3058 ( dat.north() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ||
3059 ( dat.west() == "office_tower_1" && dat.north() == "office_tower_1_entrance" ) ||
3060 ( dat.south() == "office_tower_1" && dat.west() == "office_tower_1_entrance" ) ) {
3062 " ssssssssssssssssssssssss\n"
3063 "ssssssssssssssssssssssss\n"
3064 "ss \n"
3065 "ss%%%%%%%%%%%%%%%%%%%%%%\n"
3066 "ss%|-HH-|-HH-|-HH-|HH|--\n"
3067 "ss%Vdcxl|dxdl|lddx|..|.S\n"
3068 "ss%Vdh..|dh..|..hd|..+..\n"
3069 "ss%|-..-|-..-|-..-|..|--\n"
3070 "ss%V.................|.T\n"
3071 "ss%V.................|..\n"
3072 "ss%|-..-|-..-|-..-|..|--\n"
3073 "ss%V.h..|..hd|..hd|..|..\n"
3074 "ss%Vdxdl|^dxd|.xdd|..G..\n"
3075 "ss%|----|----|----|..G..\n"
3076 "ss%|llll|..htth......|..\n"
3077 "ss%V.................|..\n"
3078 "ss%V.ddd..........|+-|..\n"
3079 "ss%|..hd|.hh.ceocc|.l|..\n"
3080 "ss%|----|---------|--|..\n"
3081 "ss%Vcdcl|...............\n"
3082 "ss%V.h..+...............\n"
3083 "ss%V...^|...|---|---|...\n"
3084 "ss%|----|...|.R>|EEE|...\n"
3085 "ss%|rrrr|...|.R.|EEED...\n", ter_key, fur_key );
3086 if( dat.monster_density() > 1 ) {
3088 } else {
3089 place_spawns( GROUP_PLAIN, 1, point( 5, 7 ), point( 15, 20 ), 0.1 );
3090 }
3091 place_items( item_group_id( "office" ), 75, point( 4, 23 ), point( 7, 23 ), false,
3093 place_items( item_group_id( "office" ), 75, point( 4, 19 ), point( 7, 19 ), false,
3095 place_items( item_group_id( "office" ), 75, point( 4, 14 ), point( 7, 14 ), false,
3097 place_items( item_group_id( "office" ), 75, point( 5, 16 ), point( 7, 16 ), false,
3099 place_items( item_group_id( "fridge" ), 80, point( 14, 17 ), point( 14, 17 ), false,
3101 place_items( item_group_id( "cleaning" ), 75, point( 19, 17 ), point( 20, 17 ), false,
3103 place_items( item_group_id( "cubical_office" ), 75, point( 6, 12 ), point( 7, 12 ), false,
3105 place_items( item_group_id( "cubical_office" ), 75, point( 12, 11 ), point( 12, 12 ), false,
3107 place_items( item_group_id( "cubical_office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3109 place_items( item_group_id( "cubical_office" ), 75, point( 4, 5 ), point( 5, 5 ), false,
3111 place_items( item_group_id( "cubical_office" ), 75, point( 11, 5 ), point( 12, 5 ), false,
3113 place_items( item_group_id( "cubical_office" ), 75, point( 14, 5 ), point( 16, 5 ), false,
3115 place_office_chairs();
3116
3117 if( dat.west() == "office_tower_1_entrance" ) {
3118 rotate( 1 );
3119 }
3120 if( dat.north() == "office_tower_1_entrance" ) {
3121 rotate( 2 );
3122 }
3123 if( dat.east() == "office_tower_1_entrance" ) {
3124 rotate( 3 );
3125 }
3126 } else if( ( dat.west() == "office_tower_1_entrance" && dat.north() == "office_tower_1" ) ||
3127 ( dat.north() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3128 ( dat.west() == "office_tower_1" && dat.south() == "office_tower_1_entrance" ) ||
3129 ( dat.south() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ) {
3131 "...DEEE|...|..|-----|%ss\n"
3132 "...|EEE|...|..|^...lV%ss\n"
3133 "...|---|-+-|......hdV%ss\n"
3134 "...........G..|..dddV%ss\n"
3135 "...........G..|-----|%ss\n"
3136 ".......|---|..|...ddV%ss\n"
3137 "|+-|...|...+......hdV%ss\n"
3138 "|.l|...|rr.|.^|l...dV%ss\n"
3139 "|--|...|---|--|-----|%ss\n"
3140 "|...........c.......V%ss\n"
3141 "|.......cxh.c.#####.Vsss\n"
3142 "|.......ccccc.......Gsss\n"
3143 "|...................Gsss\n"
3144 "|...................Vsss\n"
3145 "|#..................Gsss\n"
3146 "|#..................Gsss\n"
3147 "|#..................Vsss\n"
3148 "|#............#####.V%ss\n"
3149 "|...................|%ss\n"
3150 "--HHHHHGGHHGGHHHHH--|%ss\n"
3151 "%%%%% ssssssss %%%%%%%ss\n"
3152 " ssssssss ss\n"
3153 "ssssssssssssssssssssssss\n"
3154 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3155 place_items( item_group_id( "office" ), 75, point( 19, 1 ), point( 19, 3 ), false,
3157 place_items( item_group_id( "office" ), 75, point( 17, 3 ), point( 18, 3 ), false,
3159 place_items( item_group_id( "office" ), 90, point( 8, 7 ), point( 9, 7 ), false,
3161 place_items( item_group_id( "cubical_office" ), 75, point( 19, 5 ), point( 19, 7 ), false,
3163 place_items( item_group_id( "cleaning" ), 80, point( 1, 7 ), point( 2, 7 ), false,
3165 if( dat.monster_density() > 1 ) {
3166 place_spawns( GROUP_ZOMBIE, 2, point_zero, point( 14, 10 ), dat.monster_density() );
3167 } else {
3168 place_spawns( GROUP_PLAIN, 1, point( 10, 10 ), point( 14, 10 ), 0.15 );
3169 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3170 }
3171 place_office_chairs();
3172
3173 if( dat.north() == "office_tower_1_entrance" ) {
3174 rotate( 1 );
3175 }
3176 if( dat.east() == "office_tower_1_entrance" ) {
3177 rotate( 2 );
3178 }
3179 if( dat.south() == "office_tower_1_entrance" ) {
3180 rotate( 3 );
3181 }
3182 } else {
3184 "ssssssssssssssssssssssss\n"
3185 "ssssssssssssssssssssssss\n"
3186 " ss\n"
3187 "%%%%%%%%%%%%%%%%%%%%%%ss\n"
3188 "--|---|--HHHH-HHHH--|%ss\n"
3189 ".T|..l|............^|%ss\n"
3190 "..|-+-|...hhhhhhh...V%ss\n"
3191 "--|...G...ttttttt...V%ss\n"
3192 ".S|...G...ttttttt...V%ss\n"
3193 "..+...|...hhhhhhh...V%ss\n"
3194 "--|...|.............|%ss\n"
3195 "..|...|-------------|%ss\n"
3196 "..G....|l.......dxd^|%ss\n"
3197 "..G....G...h....dh..V%ss\n"
3198 "..|....|............V%ss\n"
3199 "..|....|------|llccc|%ss\n"
3200 "..|...........|-----|%ss\n"
3201 "..|...........|...ddV%ss\n"
3202 "..|----|---|......hdV%ss\n"
3203 ".......+...|..|l...dV%ss\n"
3204 ".......|rrr|..|-----|%ss\n"
3205 "...|---|---|..|l.dddV%ss\n"
3206 "...|xEE|.R>|......hdV%ss\n"
3207 "...DEEE|.R.|..|.....V%ss\n", ter_key, fur_key );
3208 spawn_item( point( 18, 15 ), "record_accounting" );
3209 place_items( item_group_id( "cleaning" ), 75, point( 3, 5 ), point( 5, 5 ), false,
3211 place_items( item_group_id( "office" ), 75, point( 10, 7 ), point( 16, 8 ), false,
3213 place_items( item_group_id( "cubical_office" ), 75, point( 15, 15 ), point( 19, 15 ), false,
3215 place_items( item_group_id( "cubical_office" ), 75, point( 16, 12 ), point( 16, 13 ), false,
3217 place_items( item_group_id( "cubical_office" ), 75, point( 17, 19 ), point( 19, 19 ), false,
3219 place_items( item_group_id( "office" ), 75, point( 17, 21 ), point( 19, 21 ), false,
3221 place_items( item_group_id( "office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3223 place_items( item_group_id( "cleaning" ), 75, point( 8, 20 ), point( 10, 20 ), false,
3225 if( dat.monster_density() > 1 ) {
3227 } else {
3228 place_spawns( GROUP_PLAIN, 1, point_zero, point( 9, 15 ), 0.1 );
3229 }
3230 place_office_chairs();
3231
3232 if( dat.west() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3233 rotate( 1 );
3234 } else if( dat.east() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3235 rotate( 2 );
3236 } else if( dat.east() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3237 rotate( 3 );
3238 }
3239 }
3240 } else if( terrain_type == "office_tower_b_entrance" ) {
3241 dat.fill_groundcover();
3243 "sss|........|...|EEED___\n"
3244 "sss|........|...|EEx|___\n"
3245 "sss|........|-+-|---|HHG\n"
3246 "sss|....................\n"
3247 "sss|....................\n"
3248 "sss|....................\n"
3249 "sss|....................\n"
3250 "sss|....,,......,,......\n"
3251 "sss|...,,,,.....,,......\n"
3252 "sss|....,,.....,,,,..xS.\n"
3253 "sss|....,,......,,...SS.\n"
3254 "sss|-|XXXXXX||XXXXXX|---\n"
3255 "sss|s|EEEEEE||EEEEEE|sss\n"
3256 "sss|||EEEEEE||EEEEEE|sss\n"
3257 "sss||xEEEEEE||EEEEEE||ss\n"
3258 "sss|||EEEEEE||EEEEEEx|ss\n"
3259 "sss|s|EEEEEE||EEEEEE||ss\n"
3260 "sss|s|EEEEEE||EEEEEE|sss\n"
3261 "sss|s|------||------|sss\n"
3262 "sss|--------------------\n"
3263 "ssssssssssssssssssssssss\n"
3264 "ssssssssssssssssssssssss\n"
3265 "ssssssssssssssssssssssss\n"
3266 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3267 if( dat.monster_density() > 1 ) {
3269 } else {
3271 }
3272 if( dat.north() == "office_tower_b" && dat.west() == "office_tower_b" ) {
3273 rotate( 3 );
3274 } else if( dat.north() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3275 rotate( 0 );
3276 } else if( dat.south() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3277 rotate( 1 );
3278 } else if( dat.west() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3279 rotate( 2 );
3280 }
3281 } else if( terrain_type == "office_tower_b" ) {
3282 // Init to grass & dirt;
3283 dat.fill_groundcover();
3284 if( ( dat.south() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3285 ( dat.north() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ||
3286 ( dat.west() == "office_tower_b" && dat.north() == "office_tower_b_entrance" ) ||
3287 ( dat.south() == "office_tower_b" && dat.west() == "office_tower_b_entrance" ) ) {
3289 "ssssssssssssssssssssssss\n"
3290 "ssssssssssssssssssssssss\n"
3291 "sss|--------------------\n"
3292 "sss|,.....,.....,.....,S\n"
3293 "sss|,.....,.....,.....,S\n"
3294 "sss|,.....,.....,.....,S\n"
3295 "sss|,.....,.....,.....,S\n"
3296 "sss|,.....,.....,.....,S\n"
3297 "sss|,.....,.....,.....,S\n"
3298 "sss|....................\n"
3299 "sss|....................\n"
3300 "sss|....................\n"
3301 "sss|....................\n"
3302 "sss|....................\n"
3303 "sss|....................\n"
3304 "sss|...,,...,....,....,S\n"
3305 "sss|..,,,,..,....,....,S\n"
3306 "sss|...,,...,....,....,S\n"
3307 "sss|...,,...,....,....,S\n"
3308 "sss|........,....,....,S\n"
3309 "sss|........,....,....,S\n"
3310 "sss|........|---|---|HHG\n"
3311 "sss|........|.R<|EEE|___\n"
3312 "sss|........|.R.|EEED___\n", b_ter_key, b_fur_key );
3313 if( dat.monster_density() > 1 ) {
3315 } else {
3317 }
3318 if( dat.west() == "office_tower_b_entrance" ) {
3319 rotate( 1 );
3320 if( x_in_y( 1, 5 ) ) {
3321 add_vehicle( vproto_id( "car" ), point( 17, 7 ), 180_degrees );
3322 }
3323 if( x_in_y( 1, 3 ) ) {
3324 add_vehicle( vproto_id( "motorcycle" ), point( 17, 13 ), 180_degrees );
3325 }
3326 if( x_in_y( 1, 5 ) ) {
3327 if( one_in( 3 ) ) {
3328 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3329 } else {
3330 add_vehicle( vproto_id( "pickup" ), point( 17, 19 ), 180_degrees );
3331 }
3332 }
3333 } else if( dat.north() == "office_tower_b_entrance" ) {
3334 rotate( 2 );
3335 if( x_in_y( 1, 5 ) ) {
3336 add_vehicle( vproto_id( "car" ), point( 10, 17 ), 270_degrees );
3337 }
3338 if( x_in_y( 1, 3 ) ) {
3339 add_vehicle( vproto_id( "motorcycle" ), point( 4, 18 ), 270_degrees );
3340 }
3341 if( x_in_y( 1, 5 ) ) {
3342 if( one_in( 3 ) ) {
3343 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3344 } else {
3345 add_vehicle( vproto_id( "pickup" ), point( 16, 17 ), 270_degrees );
3346 }
3347 }
3348 } else if( dat.east() == "office_tower_b_entrance" ) {
3349 rotate( 3 );
3350 if( x_in_y( 1, 5 ) ) {
3351 add_vehicle( vproto_id( "car" ), point( 6, 4 ), 0_degrees );
3352 }
3353 if( x_in_y( 1, 3 ) ) {
3354 add_vehicle( vproto_id( "motorcycle" ), point( 6, 10 ), 180_degrees );
3355 }
3356 if( x_in_y( 1, 5 ) ) {
3357 add_vehicle( vproto_id( "pickup" ), point( 6, 16 ), 0_degrees );
3358 }
3359
3360 } else {
3361 if( x_in_y( 1, 5 ) ) {
3362 add_vehicle( vproto_id( "pickup" ), point( 7, 6 ), 90_degrees );
3363 }
3364 if( x_in_y( 1, 5 ) ) {
3365 add_vehicle( vproto_id( "car" ), point( 14, 6 ), 90_degrees );
3366 }
3367 if( x_in_y( 1, 3 ) ) {
3368 add_vehicle( vproto_id( "motorcycle" ), point( 19, 6 ), 90_degrees );
3369 }
3370 }
3371 } else if( ( dat.west() == "office_tower_b_entrance" && dat.north() == "office_tower_b" ) ||
3372 ( dat.north() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3373 ( dat.west() == "office_tower_b" && dat.south() == "office_tower_b_entrance" ) ||
3374 ( dat.south() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ) {
3376 "___DEEE|...|...,,...|sss\n"
3377 "___|EEE|...|..,,,,..|sss\n"
3378 "GHH|---|-+-|...,,...|sss\n"
3379 "....................|sss\n"
3380 "....................|sss\n"
3381 "....................|sss\n"
3382 "....................|sss\n"
3383 "....................|sss\n"
3384 "....................|sss\n"
3385 "....................|sss\n"
3386 "....................|sss\n"
3387 "|...................|sss\n"
3388 "|...................|sss\n"
3389 "|,.....,.....,.....,|sss\n"
3390 "|,.....,.....,.....,|sss\n"
3391 "|,.....,.....,.....,|sss\n"
3392 "|,.....,.....,.....,|sss\n"
3393 "|,.....,.....,.....,|sss\n"
3394 "|,.....,.....,.....,|sss\n"
3395 "|-------------------|sss\n"
3396 "ssssssssssssssssssssssss\n"
3397 "ssssssssssssssssssssssss\n"
3398 "ssssssssssssssssssssssss\n"
3399 "ssssssssssssssssssssssss\n", b_ter_key, b_fur_key );
3400 if( dat.monster_density() > 1 ) {
3402 } else {
3404 }
3405 if( dat.north() == "office_tower_b_entrance" ) {
3406 rotate( 1 );
3407 if( x_in_y( 1, 5 ) ) {
3408 add_vehicle( vproto_id( "car" ), point( 8, 15 ), 0_degrees );
3409 }
3410 if( x_in_y( 1, 5 ) ) {
3411 add_vehicle( vproto_id( "pickup" ), point( 7, 10 ), 180_degrees );
3412 }
3413 if( x_in_y( 1, 3 ) ) {
3414 add_vehicle( vproto_id( "beetle" ), point( 7, 3 ), 0_degrees );
3415 }
3416 } else if( dat.east() == "office_tower_b_entrance" ) {
3417 rotate( 2 );
3418 if( x_in_y( 1, 5 ) ) {
3419 if( one_in( 3 ) ) {
3420 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3421 } else {
3422 add_vehicle( vproto_id( "pickup" ), point( 7, 7 ), 270_degrees );
3423 }
3424 }
3425 if( x_in_y( 1, 5 ) ) {
3426 add_vehicle( vproto_id( "car" ), point( 13, 8 ), 90_degrees );
3427 }
3428 if( x_in_y( 1, 3 ) ) {
3429 add_vehicle( vproto_id( "beetle" ), point( 20, 7 ), 90_degrees );
3430 }
3431 } else if( dat.south() == "office_tower_b_entrance" ) {
3432 rotate( 3 );
3433 if( x_in_y( 1, 5 ) ) {
3434 add_vehicle( vproto_id( "pickup" ), point( 16, 7 ), 0_degrees );
3435 }
3436 if( x_in_y( 1, 5 ) ) {
3437 add_vehicle( vproto_id( "car" ), point( 15, 13 ), 180_degrees );
3438 }
3439 if( x_in_y( 1, 3 ) ) {
3440 add_vehicle( vproto_id( "beetle" ), point( 15, 20 ), 180_degrees );
3441 }
3442 } else {
3443 if( x_in_y( 1, 5 ) ) {
3444 add_vehicle( vproto_id( "pickup" ), point( 16, 16 ), 90_degrees );
3445 }
3446 if( x_in_y( 1, 5 ) ) {
3447 add_vehicle( vproto_id( "car" ), point( 9, 15 ), 270_degrees );
3448 }
3449 if( x_in_y( 1, 3 ) ) {
3450 add_vehicle( vproto_id( "beetle" ), point( 4, 16 ), 270_degrees );
3451 }
3452 }
3453 } else {
3455 "ssssssssssssssssssssssss\n"
3456 "ssssssssssssssssssssssss\n"
3457 "--------------------|sss\n"
3458 "S,.....,.....,.....,|sss\n"
3459 "S,.....,.....,.....,|sss\n"
3460 "S,.....,.....,.....,|sss\n"
3461 "S,.....,.....,.....,|sss\n"
3462 "S,.....,.....,.....,|sss\n"
3463 "S,.....,.....,.....,|sss\n"
3464 "....................|sss\n"
3465 "....................|sss\n"
3466 "....................|sss\n"
3467 "....................|sss\n"
3468 "....................|sss\n"
3469 "....................|sss\n"
3470 "S,....,....,........|sss\n"
3471 "S,....,....,........|sss\n"
3472 "S,....,....,........|sss\n"
3473 "S,....,....,........|sss\n"
3474 "S,....,....,........|sss\n"
3475 "S,....,....,........|sss\n"
3476 "GHH|---|---|........|sss\n"
3477 "___|xEE|.R<|........|sss\n"
3478 "___DEEE|.R.|...,,...|sss\n", b_ter_key, b_fur_key );
3479 if( dat.monster_density() > 1 ) {
3481 } else {
3483 }
3484 if( dat.west() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3485 rotate( 1 );
3486 if( x_in_y( 1, 5 ) ) {
3487 if( one_in( 3 ) ) {
3488 add_vehicle( vproto_id( "cube_van" ), point( 17, 4 ), 180_degrees );
3489 } else {
3490 add_vehicle( vproto_id( "cube_van_cheap" ), point( 17, 4 ), 180_degrees );
3491 }
3492 }
3493 if( x_in_y( 1, 5 ) ) {
3494 add_vehicle( vproto_id( "pickup" ), point( 17, 10 ), 180_degrees );
3495 }
3496 if( x_in_y( 1, 3 ) ) {
3497 add_vehicle( vproto_id( "car" ), point( 17, 17 ), 180_degrees );
3498 }
3499 } else if( dat.east() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3500 rotate( 2 );
3501 if( x_in_y( 1, 5 ) ) {
3502 if( one_in( 3 ) ) {
3503 add_vehicle( vproto_id( "cube_van" ), point( 6, 17 ), 270_degrees );
3504 } else {
3505 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 17 ), 270_degrees );
3506 }
3507 }
3508 if( x_in_y( 1, 5 ) ) {
3509 add_vehicle( vproto_id( "pickup" ), point( 12, 17 ), 270_degrees );
3510 }
3511 if( x_in_y( 1, 3 ) ) {
3512 add_vehicle( vproto_id( "fire_truck" ), point( 18, 17 ), 270_degrees );
3513 }
3514 } else if( dat.east() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3515 rotate( 3 );
3516 if( x_in_y( 1, 5 ) ) {
3517 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 6 ), 0_degrees );
3518 }
3519 if( x_in_y( 1, 5 ) ) {
3520 if( one_in( 3 ) ) {
3521 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3522 } else {
3523 add_vehicle( vproto_id( "pickup" ), point( 6, 13 ), 0_degrees );
3524 }
3525 }
3526 if( x_in_y( 1, 3 ) ) {
3527 add_vehicle( vproto_id( "car" ), point( 5, 19 ), 180_degrees );
3528 }
3529 } else {
3530 if( x_in_y( 1, 5 ) ) {
3531 add_vehicle( vproto_id( "flatbed_truck" ), point( 16, 6 ), 90_degrees );
3532 }
3533 if( x_in_y( 1, 5 ) ) {
3534 add_vehicle( vproto_id( "cube_van_cheap" ), point( 10, 6 ), 90_degrees );
3535 }
3536 if( x_in_y( 1, 3 ) ) {
3537 add_vehicle( vproto_id( "car" ), point( 4, 6 ), 90_degrees );
3538 }
3539 }
3540 }
3541 }
3542}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
void fill_groundcover()
Definition: mapgendata.cpp:125
float monster_density() const
Definition: mapgendata.h:90
furn_id f_chair
Definition: mapdata.cpp:1105
ter_id t_door_locked_alarm
Definition: mapdata.cpp:659
furn_id f_fridge
Definition: mapdata.cpp:1108
ter_id t_wall
Definition: mapdata.cpp:648
furn_id f_bookcase
Definition: mapdata.cpp:1109
ter_id t_pavement
Definition: mapdata.cpp:632
furn_id f_desk
Definition: mapdata.cpp:1105
ter_id t_railing
Definition: mapdata.cpp:690
furn_id f_indoor_plant
Definition: mapdata.cpp:1102
ter_id t_pavement_y
Definition: mapdata.cpp:632
ter_id t_wall_glass
Definition: mapdata.cpp:650
furn_id f_crate_c
Definition: mapdata.cpp:1112
furn_id f_toilet
Definition: mapdata.cpp:1103
ter_id t_window
Definition: mapdata.cpp:668
furn_id f_bench
Definition: mapdata.cpp:1106
ter_id t_door_glass_c
Definition: mapdata.cpp:666
ter_id t_console_broken
Definition: mapdata.cpp:706
ter_id t_door_locked
Definition: mapdata.cpp:659
furn_id f_locker
Definition: mapdata.cpp:1108
ter_id t_elevator
Definition: mapdata.cpp:725
furn_id f_sink
Definition: mapdata.cpp:1104
ter_id t_door_c
Definition: mapdata.cpp:658
static const mongroup_id GROUP_ZOMBIE_COP("GROUP_ZOMBIE_COP")
static const mongroup_id GROUP_PLAIN("GROUP_PLAIN")
static const mongroup_id GROUP_ZOMBIE("GROUP_ZOMBIE")
format_effect< furn_id > furn_bind(const char(&characters)[N], Args... ids)
Definition: mapgenformat.h:76
void formatted_set_simple(map *m, point start, const char *cstr, const format_effect< ter_id > &ter_b, const format_effect< furn_id > &furn_b)
Set terrain and furniture on the supplied map.
format_effect< ter_id > ter_bind(const char(&characters)[N], Args... ids)
The functions create a mapping of characters to ids, usable with formatted_set_simple.
Definition: mapgenformat.h:66
string_id< vehicle_prototype > vproto_id
Definition: type_id.h:196

References add_vehicle(), mapgendata::east(), EAST_EDGE, f_bench, f_bookcase, f_chair, f_counter, f_crate_c, f_desk, f_fridge, f_indoor_plant, f_locker, f_null, f_rack, f_sink, f_table, f_toilet, mapgendata::fill_groundcover(), mapf::formatted_set_simple(), mapf::furn_bind(), GROUP_PLAIN, GROUP_ZOMBIE, GROUP_ZOMBIE_COP, mapgendata::monster_density(), mapgendata::north(), one_in(), place_items(), place_spawns(), point_zero, rng(), rotate(), mapgendata::south(), SOUTH_EDGE, spawn_item(), calendar::start_of_cataclysm, t_console, t_console_broken, t_door_c, t_door_glass_c, t_door_locked, t_door_locked_alarm, t_door_metal_locked, t_elevator, t_floor, t_pavement, t_pavement_y, t_railing, t_rock, t_shrub, t_sidewalk, t_stairs_down, t_stairs_up, t_wall, t_wall_glass, t_window, mapf::ter_bind(), mapgendata::terrain_type(), mapgendata::west(), and x_in_y().

Referenced by draw_map().

◆ draw_rough_circle_furn()

void map::draw_rough_circle_furn ( const furn_id type,
point  p,
int  rad 
)

Definition at line 8545 of file map.cpp.

8546{
8547 draw_rough_circle( [this, type]( point q ) {
8548 this->furn_set( q, type );
8549 }, p, rad );
8550}

References draw_rough_circle(), furn_set(), rad, and type.

Referenced by rough_circle_furn().

◆ draw_rough_circle_ter()

void map::draw_rough_circle_ter ( const ter_id type,
point  p,
int  rad 
)

Definition at line 8538 of file map.cpp.

8539{
8540 draw_rough_circle( [this, type]( point q ) {
8541 this->ter_set( q, type );
8542 }, p, rad );
8543}

References draw_rough_circle(), rad, ter_set(), and type.

Referenced by rough_circle().

◆ draw_slimepit()

void map::draw_slimepit ( mapgendata dat)
protected

Definition at line 5077 of file mapgen.cpp.

5078{
5079 const oter_id &terrain_type = dat.terrain_type();
5080 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ) {
5081 for( int i = 0; i < SEEX * 2; i++ ) {
5082 for( int j = 0; j < SEEY * 2; j++ ) {
5083 if( !one_in( 10 ) && ( j < dat.n_fac * SEEX ||
5084 i < dat.w_fac * SEEX ||
5085 j > SEEY * 2 - dat.s_fac * SEEY ||
5086 i > SEEX * 2 - dat.e_fac * SEEX ) ) {
5087 ter_set( point( i, j ), ( !one_in( 10 ) ? t_slime : t_rock_floor ) );
5088 } else if( rng( 0, SEEX ) > std::abs( i - SEEX ) && rng( 0, SEEY ) > std::abs( j - SEEY ) ) {
5089 ter_set( point( i, j ), t_slime );
5090 } else if( dat.zlevel() == 0 ) {
5091 ter_set( point( i, j ), t_dirt );
5092 } else {
5093 ter_set( point( i, j ), t_rock_floor );
5094 }
5095 }
5096 }
5097 if( terrain_type == "slimepit_down" ) {
5098 ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), t_slope_down );
5099 }
5100 if( dat.above() == "slimepit_down" ) {
5101 switch( rng( 1, 4 ) ) {
5102 case 1:
5103 ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), t_slope_up );
5104 break;
5105 case 2:
5106 ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5107 break;
5108 case 3:
5109 ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), t_slope_up );
5110 break;
5111 case 4:
5112 ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5113 }
5114 }
5115 place_spawns( GROUP_BLOB, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 );
5116 place_items( item_group_id( "sewer" ), 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true,
5118 }
5119}
static const mongroup_id GROUP_BLOB("GROUP_BLOB")

References mapgendata::above(), mapgendata::e_fac, EAST_EDGE, GROUP_BLOB, is_ot_match(), mapgendata::n_fac, one_in(), place_items(), place_spawns(), point_zero, prefix, rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH_EDGE, calendar::start_of_cataclysm, t_dirt, t_rock_floor, t_slime, t_slope_down, t_slope_up, ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_square_furn()

void map::draw_square_furn ( const furn_id type,
point  p1,
point  p2 
)

Definition at line 8515 of file map.cpp.

8516{
8517 draw_square( [this, type]( point p ) {
8518 this->furn_set( p, type );
8519 }, p1, p2 );
8520}
void draw_square(std::function< void(point)>set, point p1, point p2)

References draw_square(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and square_furn().

◆ draw_square_ter() [1/3]

◆ draw_square_ter() [2/3]

void map::draw_square_ter ( const weighted_int_list< ter_id > &  f,
point  p1,
point  p2 
)

Definition at line 8529 of file map.cpp.

8531{
8532 draw_square( [this, f]( point p ) {
8533 const ter_id *tid = f.pick();
8534 this->ter_set( p, tid != nullptr ? *tid : t_null );
8535 }, p1, p2 );
8536}
ter_id t_null
Definition: mapdata.cpp:625
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References draw_square(), weighted_list< W, T >::pick(), t_null, and ter_set().

◆ draw_square_ter() [3/3]

void map::draw_square_ter ( ter_id(*)()  f,
point  p1,
point  p2 
)

Definition at line 8522 of file map.cpp.

8523{
8524 draw_square( [this, f]( point p ) {
8525 this->ter_set( p, f() );
8526 }, p1, p2 );
8527}

References draw_square(), and ter_set().

◆ draw_temple()

void map::draw_temple ( mapgendata dat)
protected

Definition at line 4545 of file mapgen.cpp.

4546{
4547 const oter_id &terrain_type = dat.terrain_type();
4548 if( terrain_type == "temple" || terrain_type == "temple_stairs" ) {
4549 if( dat.zlevel() == 0 ) {
4550 // Ground floor
4551 // TODO: More varieties?
4552 fill_background( this, t_dirt );
4553 square( this, t_grate, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEX ) );
4554 ter_set( point( SEEX + 1, SEEY + 1 ), t_pedestal_temple );
4555 } else {
4556 // Underground! Shit's about to get interesting!
4557 // Start with all rock floor
4559 // We always start at the south and go north.
4560 // We use (y / 2 + z) % 4 to guarantee that rooms don't repeat.
4561 switch( 1 + std::abs( abs_sub.y / 2 + dat.zlevel() + 4 ) % 4 ) { // TODO: More varieties!
4562
4563 case 1:
4564 // Flame bursts
4565 square( this, t_rock, point_zero, point( SEEX - 1, SOUTH_EDGE ) );
4566 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, SOUTH_EDGE ) );
4567 for( int i = 2; i < SEEY * 2 - 4; i++ ) {
4568 add_field( {SEEX, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4569 add_field( {SEEX + 1, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4570 }
4571 break;
4572
4573 case 2:
4574 // Spreading water
4575 square( this, t_water_dp, point( 4, 4 ), point( 5, 5 ) );
4576 // replaced mon_sewer_snake spawn with GROUP_SEWER
4577 // Decide whether a group of only sewer snakes be made, probably not worth it
4578 place_spawns( GROUP_SEWER, 1, point( 4, 4 ), point( 4, 4 ), 1, true );
4579
4580 square( this, t_water_dp, point( SEEX * 2 - 5, 4 ), point( SEEX * 2 - 4, 6 ) );
4581 place_spawns( GROUP_SEWER, 1, point( 1, SEEX * 2 - 5 ), point( 1, SEEX * 2 - 5 ), 1, true );
4582
4583 square( this, t_water_dp, point( 4, SEEY * 2 - 5 ), point( 6, SEEY * 2 - 4 ) );
4584
4585 square( this, t_water_dp, point( SEEX * 2 - 5, SEEY * 2 - 5 ), point( SEEX * 2 - 4,
4586 SEEY * 2 - 4 ) );
4587
4588 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4589 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4590 line( this, t_grate, point( SEEX, 1 ), point( SEEX + 1, 1 ) ); // To drain the water
4591 mtrap_set( this, point( SEEX, SEEY * 2 - 2 ), tr_temple_flood );
4592 mtrap_set( this, point( SEEX + 1, SEEY * 2 - 2 ), tr_temple_flood );
4593 for( int y = 2; y < SEEY * 2 - 2; y++ ) {
4594 for( int x = 2; x < SEEX * 2 - 2; x++ ) {
4595 if( ter( point( x, y ) ) == t_rock_floor && one_in( 4 ) ) {
4596 mtrap_set( this, point( x, y ), tr_temple_flood );
4597 }
4598 }
4599 }
4600 break;
4601
4602 case 3: { // Flipping walls puzzle
4603 line( this, t_rock, point_zero, point( SEEX - 1, 0 ) );
4604 line( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 0 ) );
4605 line( this, t_rock, point( SEEX - 1, 1 ), point( SEEX - 1, 6 ) );
4606 line( this, t_bars, point( SEEX + 2, 1 ), point( SEEX + 2, 6 ) );
4607 ter_set( point( 14, 1 ), t_switch_rg );
4608 ter_set( point( 15, 1 ), t_switch_gb );
4609 ter_set( point( 16, 1 ), t_switch_rb );
4610 ter_set( point( 17, 1 ), t_switch_even );
4611 // Start with clear floors--then work backwards to the starting state
4612 line( this, t_floor_red, point( SEEX, 1 ), point( SEEX + 1, 1 ) );
4613 line( this, t_floor_green, point( SEEX, 2 ), point( SEEX + 1, 2 ) );
4614 line( this, t_floor_blue, point( SEEX, 3 ), point( SEEX + 1, 3 ) );
4615 line( this, t_floor_red, point( SEEX, 4 ), point( SEEX + 1, 4 ) );
4616 line( this, t_floor_green, point( SEEX, 5 ), point( SEEX + 1, 5 ) );
4617 line( this, t_floor_blue, point( SEEX, 6 ), point( SEEX + 1, 6 ) );
4618 // Now, randomly choose actions
4619 // Set up an actions vector so that there's not undue repetition
4620 std::vector<int> actions;
4621 actions.push_back( 1 );
4622 actions.push_back( 2 );
4623 actions.push_back( 3 );
4624 actions.push_back( 4 );
4625 actions.push_back( rng( 1, 3 ) );
4626 while( !actions.empty() ) {
4627 const int action = random_entry_removed( actions );
4628 for( int y = 1; y < 7; y++ ) {
4629 for( int x = SEEX; x <= SEEX + 1; x++ ) {
4630 switch( action ) {
4631 case 1:
4632 // Toggle RG
4633 if( ter( point( x, y ) ) == t_floor_red ) {
4634 ter_set( point( x, y ), t_rock_red );
4635 } else if( ter( point( x, y ) ) == t_rock_red ) {
4636 ter_set( point( x, y ), t_floor_red );
4637 } else if( ter( point( x, y ) ) == t_floor_green ) {
4638 ter_set( point( x, y ), t_rock_green );
4639 } else if( ter( point( x, y ) ) == t_rock_green ) {
4640 ter_set( point( x, y ), t_floor_green );
4641 }
4642 break;
4643 case 2:
4644 // Toggle GB
4645 if( ter( point( x, y ) ) == t_floor_blue ) {
4646 ter_set( point( x, y ), t_rock_blue );
4647 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4648 ter_set( point( x, y ), t_floor_blue );
4649 } else if( ter( point( x, y ) ) == t_floor_green ) {
4650 ter_set( point( x, y ), t_rock_green );
4651 } else if( ter( point( x, y ) ) == t_rock_green ) {
4652 ter_set( point( x, y ), t_floor_green );
4653 }
4654 break;
4655 case 3:
4656 // Toggle RB
4657 if( ter( point( x, y ) ) == t_floor_blue ) {
4658 ter_set( point( x, y ), t_rock_blue );
4659 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4660 ter_set( point( x, y ), t_floor_blue );
4661 } else if( ter( point( x, y ) ) == t_floor_red ) {
4662 ter_set( point( x, y ), t_rock_red );
4663 } else if( ter( point( x, y ) ) == t_rock_red ) {
4664 ter_set( point( x, y ), t_floor_red );
4665 }
4666 break;
4667 case 4:
4668 // Toggle Even
4669 if( y % 2 == 0 ) {
4670 if( ter( point( x, y ) ) == t_floor_blue ) {
4671 ter_set( point( x, y ), t_rock_blue );
4672 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4673 ter_set( point( x, y ), t_floor_blue );
4674 } else if( ter( point( x, y ) ) == t_floor_red ) {
4675 ter_set( point( x, y ), t_rock_red );
4676 } else if( ter( point( x, y ) ) == t_rock_red ) {
4677 ter_set( point( x, y ), t_floor_red );
4678 } else if( ter( point( x, y ) ) == t_floor_green ) {
4679 ter_set( point( x, y ), t_rock_green );
4680 } else if( ter( point( x, y ) ) == t_rock_green ) {
4681 ter_set( point( x, y ), t_floor_green );
4682 }
4683 }
4684 break;
4685 }
4686 }
4687 }
4688 }
4689 }
4690 break;
4691
4692 case 4: { // Toggling walls maze
4693 square( this, t_rock, point_zero, point( SEEX - 1, 1 ) );
4694 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4695 square( this, t_rock, point( 0, 2 ), point( SEEX - 4, SEEY * 2 - 3 ) );
4696 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 1 ) );
4697 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4698 square( this, t_rock, point( SEEX + 5, 2 ), point( EAST_EDGE, SEEY * 2 - 3 ) );
4699 int x = rng( SEEX - 1, SEEX + 2 ), y = 2;
4700 std::vector<point> path; // Path, from end to start
4701 while( x < SEEX - 1 || x > SEEX + 2 || y < SEEY * 2 - 2 ) {
4702 static const std::vector<ter_id> terrains = {
4704 };
4705 path.push_back( point( x, y ) );
4706 ter_set( point( x, y ), random_entry( terrains ) );
4707 if( y == SEEY * 2 - 2 ) {
4708 if( x < SEEX - 1 ) {
4709 x++;
4710 } else if( x > SEEX + 2 ) {
4711 x--;
4712 }
4713 } else {
4714 std::vector<point> next;
4715 for( int nx = x - 1; nx <= x + 1; nx++ ) {
4716 for( int ny = y; ny <= y + 1; ny++ ) {
4717 if( ter( point( nx, ny ) ) == t_rock_floor ) {
4718 next.push_back( point( nx, ny ) );
4719 }
4720 }
4721 }
4722 if( next.empty() ) {
4723 break;
4724 } else {
4725 const point p = random_entry( next );
4726 x = p.x;
4727 y = p.y;
4728 }
4729 }
4730 }
4731 // Now go backwards through path (start to finish), toggling any tiles that need
4732 bool toggle_red = false;
4733 bool toggle_green = false;
4734 bool toggle_blue = false;
4735 for( int i = path.size() - 1; i >= 0; i-- ) {
4736 if( ter( path[i] ) == t_floor_red ) {
4737 toggle_green = !toggle_green;
4738 if( toggle_red ) {
4739 ter_set( path[i], t_rock_red );
4740 }
4741 } else if( ter( path[i] ) == t_floor_green ) {
4742 toggle_blue = !toggle_blue;
4743 if( toggle_green ) {
4744 ter_set( path[i], t_rock_green );
4745 }
4746 } else if( ter( path[i] ) == t_floor_blue ) {
4747 toggle_red = !toggle_red;
4748 if( toggle_blue ) {
4749 ter_set( path[i], t_rock_blue );
4750 }
4751 }
4752 }
4753 // Finally, fill in the rest with random tiles, and place toggle traps
4754 for( int i = SEEX - 3; i <= SEEX + 4; i++ ) {
4755 for( int j = 2; j <= SEEY * 2 - 2; j++ ) {
4756 mtrap_set( this, point( i, j ), tr_temple_toggle );
4757 if( ter( point( i, j ) ) == t_rock_floor ) {
4758 static const std::vector<ter_id> terrains = {
4761 };
4762 ter_set( point( i, j ), random_entry( terrains ) );
4763 }
4764 }
4765 }
4766 }
4767 break;
4768 } // Done with room type switch
4769 // Stairs down if we need them
4770 if( terrain_type == "temple_stairs" ) {
4771 line( this, t_stairs_down, point( SEEX, 0 ), point( SEEX + 1, 0 ) );
4772 }
4773 // Stairs at the south if dat.above() has stairs down.
4774 if( dat.above() == "temple_stairs" ) {
4775 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4776 }
4777
4778 } // Done with underground-only stuff
4779 } else if( terrain_type == "temple_finale" ) {
4780 fill_background( this, t_rock );
4781 square( this, t_rock_floor, point( SEEX - 1, 1 ), point( SEEX + 2, 4 ) );
4782 square( this, t_rock_floor, point( SEEX, 5 ), point( SEEX + 1, SOUTH_EDGE ) );
4783 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4784 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4785 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4786 return;
4787
4788 }
4789}
@ action
Definition: dialogue.h:36
ter_id t_switch_even
Definition: mapdata.cpp:729
ter_id t_rock_red
Definition: mapdata.cpp:728
ter_id t_pedestal_temple
Definition: mapdata.cpp:726
ter_id t_floor_blue
Definition: mapdata.cpp:728
ter_id t_grate
Definition: mapdata.cpp:638
ter_id t_switch_rb
Definition: mapdata.cpp:729
ter_id t_rock_green
Definition: mapdata.cpp:728
ter_id t_rock_blue
Definition: mapdata.cpp:728
ter_id t_floor_green
Definition: mapdata.cpp:728
ter_id t_switch_gb
Definition: mapdata.cpp:729
ter_id t_floor_red
Definition: mapdata.cpp:728
ter_id t_switch_rg
Definition: mapdata.cpp:729
static const mongroup_id GROUP_SEWER("GROUP_SEWER")
static const trap_str_id tr_temple_flood("tr_temple_flood")
generic_factory< oter_t > terrains("overmap terrain")
V random_entry_removed(C &container)
Returns a random entry in the container and removes it from the container.
Definition: rng.h:170
trap_id tr_temple_toggle
Definition: trap.cpp:311

References mapgendata::above(), abs_sub, action, add_field(), EAST_EDGE, fd_fire_vent, fill_background(), GROUP_SEWER, line(), mtrap_set(), one_in(), place_spawns(), point_zero, random_entry(), random_entry_removed(), rng(), SEEX, SEEY, SOUTH_EDGE, spawn_artifact(), square(), t_bars, t_dirt, t_floor_blue, t_floor_green, t_floor_red, t_grate, t_pedestal_temple, t_rock, t_rock_blue, t_rock_floor, t_rock_green, t_rock_red, t_stairs_down, t_stairs_up, t_switch_even, t_switch_gb, t_switch_rb, t_switch_rg, t_water_dp, ter(), ter_set(), mapgendata::terrain_type(), anonymous_namespace{overmap.cpp}::terrains, tr_temple_flood, tr_temple_toggle, point::x, point::y, tripoint::y, tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_triffid()

void map::draw_triffid ( mapgendata dat)
protected

Definition at line 5121 of file mapgen.cpp.

5122{
5123 const oter_id &terrain_type = dat.terrain_type();
5124 if( terrain_type == "triffid_roots" ) {
5126 int node = 0;
5127 int step = 0;
5128 bool node_built[16];
5129 bool done = false;
5130 for( auto &elem : node_built ) {
5131 elem = false;
5132 }
5133 do {
5134 node_built[node] = true;
5135 step++;
5136 point node2( 1 + 6 * ( node % 4 ), 1 + 6 * static_cast<int>( node / 4 ) );
5137 // Clear a 4x4 dirt square
5138 square( this, t_dirt, node2, node2 + point( 3, 3 ) );
5139 // Spawn a monster in there
5140 if( step > 2 ) { // First couple of chambers are safe
5141 int monrng = rng( 1, 25 );
5142 point spawn( node2 + point{ rng( 0, 3 ), rng( 0, 3 ) } );
5143 if( monrng <= 24 ) {
5145 node2 + point( 3, 3 ), 1, true );
5146 } else {
5147 for( int webx = node2.x; webx <= node2.x + 3; webx++ ) {
5148 for( int weby = node2.y; weby <= node2.y + 3; weby++ ) {
5149 add_field( {webx, weby, abs_sub.z}, fd_web, rng( 1, 3 ) );
5150 }
5151 }
5152 place_spawns( GROUP_SPIDER, 1, spawn, spawn, 1, true );
5153 }
5154 }
5155 // TODO: Non-monster hazards?
5156 // Next, pick a cell to move to
5157 std::vector<direction> move;
5158 if( node % 4 > 0 && !node_built[node - 1] ) {
5159 move.push_back( direction::WEST );
5160 }
5161 if( node % 4 < 3 && !node_built[node + 1] ) {
5162 move.push_back( direction::EAST );
5163 }
5164 if( static_cast<int>( node / 4 ) > 0 && !node_built[node - 4] ) {
5165 move.push_back( direction::NORTH );
5166 }
5167 if( static_cast<int>( node / 4 ) < 3 && !node_built[node + 4] ) {
5168 move.push_back( direction::SOUTH );
5169 }
5170
5171 if( move.empty() ) { // Nowhere to go!
5172 square( this, t_slope_down, node2 + point_south_east, node2 + point( 2, 2 ) );
5173 done = true;
5174 } else {
5175 switch( random_entry( move ) ) {
5176 case direction::NORTH:
5177 square( this, t_dirt, node2 + point( 1, -2 ), node2 + point( 2, -1 ) );
5178 node -= 4;
5179 break;
5180 case direction::EAST:
5181 square( this, t_dirt, node2 + point( 4, 1 ), node2 + point( 5, 2 ) );
5182 node++;
5183 break;
5184 case direction::SOUTH:
5185 square( this, t_dirt, node2 + point( 1, 4 ), node2 + point( 2, 5 ) );
5186 node += 4;
5187 break;
5188 case direction::WEST:
5189 square( this, t_dirt, node2 + point( -2, 1 ), node2 + point( -1, 2 ) );
5190 node--;
5191 break;
5192 default:
5193 break;
5194 }
5195 }
5196 } while( !done );
5197 square( this, t_slope_up, point( 2, 2 ), point( 3, 3 ) );
5198 rotate( rng( 0, 3 ) );
5199 } else if( terrain_type == "triffid_finale" ) {
5201 // NOLINTNEXTLINE(cata-use-named-point-constants)
5202 square( this, t_dirt, point( 1, 1 ), point( 4, 4 ) );
5203 square( this, t_dirt, point( 19, 19 ), point( 22, 22 ) );
5204 // Drunken walk until we reach the heart (lower right, [19, 19])
5205 // Chance increases by 1 each turn, and gives the % chance of forcing a move
5206 // to the right or down.
5207 int chance = 0;
5208 int x = 4;
5209 int y = 4;
5210 do {
5211 ter_set( point( x, y ), t_dirt );
5212
5213 if( chance >= 10 && one_in( 10 ) ) { // Add a spawn
5214 place_spawns( GROUP_TRIFFID, 1, point( x, y ), point( x, y ), 1, true );
5215 }
5216
5217 if( rng( 0, 99 ) < chance ) { // Force movement down or to the right
5218 if( x >= 19 ) {
5219 y++;
5220 } else if( y >= 19 ) {
5221 x++;
5222 } else {
5223 if( one_in( 2 ) ) {
5224 x++;
5225 } else {
5226 y++;
5227 }
5228 }
5229 } else {
5230 chance++; // Increase chance of forced movement down/right
5231 // Weigh movement towards directions with lots of existing walls
5232 int chance_west = 0;
5233 int chance_east = 0;
5234 int chance_north = 0;
5235 int chance_south = 0;
5236 for( int dist = 1; dist <= 5; dist++ ) {
5237 if( ter( point( x - dist, y ) ) == t_root_wall ) {
5238 chance_west++;
5239 }
5240 if( ter( point( x + dist, y ) ) == t_root_wall ) {
5241 chance_east++;
5242 }
5243 if( ter( point( x, y - dist ) ) == t_root_wall ) {
5244 chance_north++;
5245 }
5246 if( ter( point( x, y + dist ) ) == t_root_wall ) {
5247 chance_south++;
5248 }
5249 }
5250 int roll = rng( 0, chance_west + chance_east + chance_north + chance_south );
5251 if( roll < chance_west && x > 0 ) {
5252 x--;
5253 } else if( roll < chance_west + chance_east && x < EAST_EDGE ) {
5254 x++;
5255 } else if( roll < chance_west + chance_east + chance_north && y > 0 ) {
5256 y--;
5257 } else if( y < SOUTH_EDGE ) {
5258 y++;
5259 }
5260 } // Done with drunken walk
5261 } while( x < 19 || y < 19 );
5262 // NOLINTNEXTLINE(cata-use-named-point-constants)
5263 square( this, t_slope_up, point( 1, 1 ), point( 2, 2 ) );
5264 place_spawns( GROUP_TRIFFID_HEART, 1, point( 21, 21 ), point( 21, 21 ), 1, true );
5265
5266 }
5267}
ter_id t_root_wall
Definition: mapdata.cpp:686
static const mongroup_id GROUP_TRIFFID_OUTER("GROUP_TRIFFID_OUTER")
static const mongroup_id GROUP_SPIDER("GROUP_SPIDER")
static const mongroup_id GROUP_TRIFFID("GROUP_TRIFFID")
static const mongroup_id GROUP_TRIFFID_HEART("GROUP_TRIFFID_HEART")

References abs_sub, add_field(), detail::digits::done, EAST, EAST_EDGE, fd_web, fill_background(), GROUP_SPIDER, GROUP_TRIFFID, GROUP_TRIFFID_HEART, GROUP_TRIFFID_OUTER, avatar_action::move(), NORTH, one_in(), place_spawns(), point_south_east, random_entry(), rng(), rotate(), SOUTH, SOUTH_EDGE, square(), t_dirt, t_root_wall, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), WEST, point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ drawsq()

void map::drawsq ( const catacurses::window w,
const tripoint p,
const drawsq_params params 
) const

Draw the map tile at the given coordinate.

Called by map::draw().

Parameters
wThe window we are drawing in
pThe tile on this map to draw.
paramsDraw parameters.

Definition at line 5938 of file map.cpp.

5940{
5941 // If we are in tiles mode, the only thing we want to potentially draw is a highlight
5942 if( is_draw_tiles_mode() ) {
5943 if( params.highlight() ) {
5944 g->draw_highlight( p );
5945 }
5946 return;
5947 }
5948
5949 if( !inbounds( p ) ) {
5950 return;
5951 }
5952
5953 const tripoint view_center = params.center();
5954 const int k = p.x + getmaxx( w ) / 2 - view_center.x;
5955 const int j = p.y + getmaxy( w ) / 2 - view_center.y;
5956 wmove( w, point( k, j ) );
5957
5958 const maptile tile = maptile_at( p );
5959 if( draw_maptile( w, p, tile, params ) ) {
5960 return;
5961 }
5962
5963 tripoint below( p.xy(), p.z - 1 );
5964 const maptile tile_below = maptile_at( below );
5965 draw_from_above( w, below, tile_below, params );
5966}
maptile maptile_at(const tripoint &p) const
Definition: map.cpp:260
constexpr drawsq_params & center(const tripoint &p)
Set view center.
Definition: map.h:283

References drawsq_params::center(), draw_from_above(), draw_maptile(), g, catacurses::getmaxx(), catacurses::getmaxy(), drawsq_params::highlight(), inbounds(), is_draw_tiles_mode(), maptile_at(), catacurses::wmove(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by choose_adjacent_highlight(), anonymous_namespace{animation.cpp}::draw_line_curses(), game::draw_look_around_cursor(), editmap::draw_main_ui_overlay(), target_ui::draw_terrain_overlay(), game::pickup(), place_construction(), and editmap::uber_draw_ter().

◆ drop_everything()

void map::drop_everything ( const tripoint p)

Handles map objects of given type (not creatures) falling down.

Returns true if anything changed.

Definition at line 2126 of file map.cpp.

2127{
2128 //Do a suspension check so that there won't be a floor there for the rest of this check.
2129 if( has_flag( "SUSPENDED", p ) ) {
2131 }
2132 if( has_floor( p ) ) {
2133 return;
2134 }
2135
2136 drop_furniture( p );
2137 drop_items( p );
2138 drop_vehicle( p );
2139 drop_fields( p );
2140}
void drop_furniture(const tripoint &p)
Definition: map.cpp:2142
void drop_items(const tripoint &p)
Definition: map.cpp:2284
void drop_vehicle(const tripoint &p)
Definition: map.cpp:2314
void collapse_invalid_suspension(const tripoint &point)
Triggers a recursive collapse of suspended tiles based on their support validity.
Definition: map.cpp:3013
void drop_fields(const tripoint &p)
Definition: map.cpp:2324
bool has_floor(const tripoint &p) const
Definition: map.cpp:2071

References collapse_invalid_suspension(), drop_fields(), drop_furniture(), drop_items(), drop_vehicle(), has_flag(), and has_floor().

Referenced by process_falling().

◆ drop_fields()

void map::drop_fields ( const tripoint p)

Definition at line 2324 of file map.cpp.

2325{
2326 field &fld = field_at( p );
2327 if( fld.field_count() == 0 ) {
2328 return;
2329 }
2330
2331 std::list<field_type_id> dropped;
2332 const tripoint below = p + tripoint_below;
2333 for( const auto &iter : fld ) {
2334 const field_entry &entry = iter.second;
2335 // For now only drop cosmetic fields, which don't warrant per-turn check
2336 // Active fields "drop themselves"
2337 if( entry.decays_on_actualize() ) {
2338 add_field( below, entry.get_field_type(), entry.get_field_intensity(), entry.get_field_age() );
2339 dropped.push_back( entry.get_field_type() );
2340 }
2341 }
2342
2343 for( const auto &entry : dropped ) {
2344 fld.remove_field( entry );
2345 }
2346}
bool decays_on_actualize() const
Definition: field.h:105

References add_field(), field_entry::decays_on_actualize(), field_at(), field::field_count(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field::remove_field(), and tripoint_below.

Referenced by drop_everything().

◆ drop_furniture()

void map::drop_furniture ( const tripoint p)

Definition at line 2142 of file map.cpp.

2143{
2144 const furn_id frn = furn( p );
2145 if( frn == f_null ) {
2146 return;
2147 }
2148
2149 enum support_state {
2150 SS_NO_SUPPORT = 0,
2151 SS_BAD_SUPPORT, // TODO: Implement bad, shaky support
2152 SS_GOOD_SUPPORT,
2153 SS_FLOOR, // Like good support, but bash floor instead of tile below
2154 SS_CREATURE
2155 };
2156
2157 // Checks if the tile:
2158 // has floor (supports unconditionally)
2159 // has support below
2160 // has unsupporting furniture below (bad support, things should "slide" if possible)
2161 // has no support and thus allows things to fall through
2162 const auto check_tile = [this]( const tripoint & pt ) {
2163 if( has_floor( pt ) ) {
2164 return SS_FLOOR;
2165 }
2166
2167 tripoint below_dest( pt.xy(), pt.z - 1 );
2168 if( supports_above( below_dest ) ) {
2169 return SS_GOOD_SUPPORT;
2170 }
2171
2172 const furn_id frn_id = furn( below_dest );
2173 if( frn_id != f_null ) {
2174 const furn_t &frn = frn_id.obj();
2175 // Allow crushing tiny/nocollide furniture
2176 if( !frn.has_flag( "TINY" ) && !frn.has_flag( "NOCOLLIDE" ) ) {
2177 return SS_BAD_SUPPORT;
2178 }
2179 }
2180
2181 if( g->critter_at( below_dest ) != nullptr ) {
2182 // Smash a critter
2183 return SS_CREATURE;
2184 }
2185
2186 return SS_NO_SUPPORT;
2187 };
2188
2189 tripoint current( p.xy(), p.z + 1 );
2190 support_state last_state = SS_NO_SUPPORT;
2191 while( last_state == SS_NO_SUPPORT ) {
2192 current.z--;
2193 // Check current tile
2194 last_state = check_tile( current );
2195 }
2196
2197 if( current == p ) {
2198 // Nothing happened
2199 if( last_state != SS_FLOOR ) {
2200 support_dirty( current );
2201 }
2202
2203 return;
2204 }
2205
2206 furn_set( p, f_null );
2207 furn_set( current, frn );
2208
2209 // If it's sealed, we need to drop items with it
2210 const auto &frn_obj = frn.obj();
2211 if( frn_obj.has_flag( TFLAG_SEALED ) && has_items( p ) ) {
2212 auto old_items = i_at( p );
2213 auto new_items = i_at( current );
2214 for( const auto &it : old_items ) {
2215 new_items.insert( it );
2216 }
2217
2218 i_clear( p );
2219 }
2220
2221 // Approximate weight/"bulkiness" based on strength to drag
2222 int weight;
2223 if( frn_obj.has_flag( "TINY" ) || frn_obj.has_flag( "NOCOLLIDE" ) ) {
2224 weight = 5;
2225 } else {
2226 weight = frn_obj.is_movable() ? frn_obj.move_str_req : 20;
2227 }
2228
2229 if( frn_obj.has_flag( "ROUGH" ) || frn_obj.has_flag( "SHARP" ) ) {
2230 weight += 5;
2231 }
2232
2233 // TODO: Balance this.
2234 int dmg = weight * ( p.z - current.z );
2235
2236 if( last_state == SS_FLOOR ) {
2237 // Bash the same tile twice - once for furniture, once for the floor
2238 bash( current, dmg, false, false, true );
2239 bash( current, dmg, false, false, true );
2240 } else if( last_state == SS_BAD_SUPPORT || last_state == SS_GOOD_SUPPORT ) {
2241 bash( current, dmg, false, false, false );
2242 tripoint below( current.xy(), current.z - 1 );
2243 bash( below, dmg, false, false, false );
2244 } else if( last_state == SS_CREATURE ) {
2245 const std::string &furn_name = frn_obj.name();
2246 bash( current, dmg, false, false, false );
2247 tripoint below( current.xy(), current.z - 1 );
2248 Creature *critter = g->critter_at( below );
2249 if( critter == nullptr ) {
2250 debugmsg( "drop_furniture couldn't find creature at %d,%d,%d",
2251 below.x, below.y, below.z );
2252 return;
2253 }
2254
2255 critter->add_msg_player_or_npc( m_bad, _( "Falling %s hits you!" ),
2256 _( "Falling %s hits <npcname>" ),
2257 furn_name );
2258 // TODO: A chance to dodge/uncanny dodge
2259 player *pl = dynamic_cast<player *>( critter );
2260 monster *mon = dynamic_cast<monster *>( critter );
2261 if( pl != nullptr ) {
2262 pl->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2263 0.5f ) );
2264 pl->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2265 0.5f ) );
2266 pl->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2267 0.4f ) );
2268 pl->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2269 0.4f ) );
2270 pl->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2271 0.4f ) );
2272 pl->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2273 0.4f ) );
2274 } else if( mon != nullptr ) {
2275 // TODO: Monster's armor and size - don't crush hulks with chairs
2276 mon->apply_damage( nullptr, bodypart_id( "torso" ), rng( dmg, dmg * 2 ) );
2277 }
2278 }
2279
2280 // Re-queue for another check, in case bash destroyed something
2281 support_dirty( current );
2282}
bool supports_above(const tripoint &p) const
Does this tile support vehicles and furniture above it.
Definition: map.cpp:2101
void apply_damage(Creature *source, bodypart_id bp, int dam, bool bypass_med=false) override
Definition: monster.cpp:1669

References _, Creature::add_msg_player_or_npc(), monster::apply_damage(), bash(), Character::deal_damage(), debugmsg, DT_BASH, f_null, furn(), furn_set(), g, map_data_common_t::has_flag(), has_floor(), has_items(), i_at(), i_clear(), m_bad, int_id< T >::obj(), rng(), support_dirty(), supports_above(), TFLAG_SEALED, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by drop_everything().

◆ drop_items()

void map::drop_items ( const tripoint p)

Definition at line 2284 of file map.cpp.

2285{
2286 if( !has_items( p ) ) {
2287 return;
2288 }
2289
2290 auto items = i_at( p );
2291 // TODO: Make items check the volume tile below can accept
2292 // rather than disappearing if it would be overloaded
2293
2294 tripoint below( p );
2295 while( !has_floor( below ) ) {
2296 below.z--;
2297 }
2298
2299 if( below == p ) {
2300 return;
2301 }
2302
2303 for( const auto &i : items ) {
2304 // TODO: Bash the item up before adding it
2305 // TODO: Bash the creature, terrain, furniture and vehicles on the tile
2306 add_item_or_charges( below, i );
2307 }
2308
2309 // Just to make a sound for now
2310 bash( below, 1 );
2311 i_clear( p );
2312}

References add_item_or_charges(), bash(), has_floor(), has_items(), i_at(), i_clear(), and tripoint::z.

Referenced by drop_everything().

◆ drop_vehicle()

void map::drop_vehicle ( const tripoint p)

Definition at line 2314 of file map.cpp.

2315{
2316 const optional_vpart_position vp = veh_at( p );
2317 if( !vp ) {
2318 return;
2319 }
2320
2321 vp->vehicle().is_falling = true;
2322}

References veh_at().

Referenced by drop_everything().

◆ emit_field()

void map::emit_field ( const tripoint pos,
const emit_id src,
float  mul = 1.0f 
)

Runs one cycle of emission src which may result in propagation of fields.

Parameters
posLocation of emission
srcId of object producing the emission
mulMultiplies the chance and possibly qty (if chance*mul > 100) of the emission

Definition at line 1927 of file map_field.cpp.

1928{
1929 if( !src.is_valid() ) {
1930 return;
1931 }
1932
1933 const float chance = src->chance() * mul;
1934 if( src.is_valid() && x_in_y( chance, 100 ) ) {
1935 const int qty = chance > 100.0f ? roll_remainder( src->qty() * chance / 100.0f ) : src->qty();
1936 propagate_field( pos, src->field(), qty, src->intensity() );
1937 }
1938}
int intensity() const
Intensity of output fields, range [1..maximum_intensity].
Definition: emit.h:34
int qty() const
Units of field to generate per turn subject to chance.
Definition: emit.h:39
int chance() const
Chance to emit each turn, range [1..100].
Definition: emit.h:44
field_type_id field() const
Type of field to emit.
Definition: emit.h:29
void propagate_field(const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
Definition: map_field.cpp:1940
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:67
int roll_remainder(double value)
Definition: rng.cpp:96

References emit::chance(), emit::field(), emit::intensity(), string_id< T >::is_valid(), propagate_field(), emit::qty(), roll_remainder(), and x_in_y().

Referenced by enchantment::activate_passive(), Character::burn_fuel(), game::do_turn(), Character::heat_emission(), Character::passive_power_gen(), item::process_internal(), projectile_attack(), and emit_actor::use().

◆ examine()

void map::examine ( Character p,
const tripoint pos 
)

Calls the examine function of furniture or terrain at given tile, for given character.

Examines the tile pos, with character as the "examinator" Casts Character to player because player/NPC split isn't done yet.

Will only examine terrain if furniture had iexamine::none as the examine function.

Definition at line 1684 of file map.cpp.

1685{
1686 const auto furn_here = furn( pos ).obj();
1687 if( furn_here.examine != iexamine::none ) {
1688 furn_here.examine( dynamic_cast<player &>( p ), pos );
1689 } else {
1690 ter( pos ).obj().examine( dynamic_cast<player &>( p ), pos );
1691 }
1692}
void none(player &p, const tripoint &examp)
Nothing player can interact with here.
Definition: iexamine.cpp:252
iexamine_function examine
Definition: mapdata.h:402

References map_data_common_t::examine, furn(), iexamine::none(), int_id< T >::obj(), wrapped_vehicle::pos, and ter().

Referenced by npc::pick_up_item(), and water_from().

◆ features() [1/2]

std::string map::features ( const tripoint p)

Definition at line 1778 of file map.cpp.

1779{
1780 std::string result;
1781 const auto add = [&]( const std::string & text ) {
1782 if( !result.empty() ) {
1783 result += " ";
1784 }
1785 result += text;
1786 };
1787 const auto add_if = [&]( const bool cond, const std::string & text ) {
1788 if( cond ) {
1789 add( text );
1790 }
1791 };
1792 // This is used in an info window that is 46 characters wide, and is expected
1793 // to take up one line. So, make sure it does that.
1794 // FIXME: can't control length of localized text.
1795 add_if( is_bashable( p ), _( "Smashable." ) );
1796 add_if( has_flag( "DIGGABLE", p ), _( "Diggable." ) );
1797 add_if( has_flag( "PLOWABLE", p ), _( "Plowable." ) );
1798 add_if( has_flag( "ROUGH", p ), _( "Rough." ) );
1799 add_if( has_flag( "UNSTABLE", p ), _( "Unstable." ) );
1800 add_if( has_flag( "SHARP", p ), _( "Sharp." ) );
1801 add_if( has_flag( "FLAT", p ), _( "Flat." ) );
1802 add_if( has_flag( "EASY_DECONSTRUCT", p ), _( "Simple." ) );
1803 add_if( has_flag( "MOUNTABLE", p ), _( "Mountable." ) );
1804 return result;
1805}
bool is_bashable(const tripoint &p, bool allow_floor=false) const
Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.
Definition: map.cpp:2506
type add(type dir1, type dir2)
Returns a sum of two numbers.
Definition: overmap.cpp:4193

References _, om_direction::add(), has_flag(), and is_bashable().

Referenced by features(), game::print_terrain_info(), and editmap::update_view_with_help().

◆ features() [2/2]

std::string map::features ( point  p)
inline

Definition at line 899 of file map.h.

899 {
900 return features( tripoint( p, abs_sub.z ) );
901 }
std::string features(const tripoint &p)
Definition: map.cpp:1778

References abs_sub, features(), and tripoint::z.

◆ field_at() [1/2]

field & map::field_at ( const tripoint p)

Gets fields that are here.

Both for querying and edition.

Definition at line 5413 of file map.cpp.

5414{
5415 if( !inbounds( p ) ) {
5416 nulfield = field();
5417 return nulfield;
5418 }
5419
5420 point l;
5421 submap *const current_submap = get_submap_at( p, l );
5422
5423 return current_submap->get_field( l );
5424}
static field nulfield
Definition: map.cpp:142
@ field
Consumes field to recharge.

References field, submap::get_field(), get_submap_at(), inbounds(), and nulfield.

◆ field_at() [2/2]

const field & map::field_at ( const tripoint p) const

Get the fields that are here.

This is for querying and looking at it only, one can not change the fields.

Parameters
pThe local map coordinates, if out of bounds, returns an empty field.

Definition at line 5397 of file map.cpp.

5398{
5399 if( !inbounds( p ) ) {
5400 nulfield = field();
5401 return nulfield;
5402 }
5403
5404 point l;
5405 submap *const current_submap = get_submap_at( p, l );
5406
5407 return current_submap->get_field( l );
5408}

References field, submap::get_field(), get_submap_at(), inbounds(), and nulfield.

Referenced by npc::could_move_onto(), dangerous_field_at(), decay_cosmetic_fields(), character_funcs::do_pause(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_fields(), get_convection_temperature(), game::get_dangerous_tile(), get_field(), get_field_age(), get_field_intensity(), npc::good_escape_direction(), advanced_inv_area::init(), mop_spills(), character_funcs::pick_safe_adjacent_tile(), game::print_fields_info(), process_fields_in_submap(), relic_funcs::process_recharge_entry(), smash(), spell_move(), and Character::symbol_color().

◆ fill_funnels()

void map::fill_funnels ( const tripoint p,
const time_point since 
)
protected

Try to fill funnel based items here.

Simulates rain from since till now.

Parameters
pThe location in this map where to fill funnels.

Definition at line 7239 of file map.cpp.

7240{
7241 const auto &tr = tr_at( p );
7242 if( !tr.is_funnel() ) {
7243 return;
7244 }
7245 // Note: the inside/outside cache might not be correct at this time
7247 return;
7248 }
7249 auto items = i_at( p );
7250 units::volume maxvolume = 0_ml;
7251 auto biggest_container = items.end();
7252 for( auto candidate = items.begin(); candidate != items.end(); ++candidate ) {
7253 if( candidate->is_funnel_container( maxvolume ) ) {
7254 biggest_container = candidate;
7255 }
7256 }
7257 if( biggest_container != items.end() ) {
7258 retroactively_fill_from_funnel( *biggest_container, tr, since, calendar::turn, getabs( p ) );
7259 }
7260}
void retroactively_fill_from_funnel(item &it, const trap &tr, const time_point &start, const time_point &end, const tripoint &pos)
Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
Definition: weather.cpp:184

References getabs(), has_flag_ter_or_furn(), i_at(), retroactively_fill_from_funnel(), TFLAG_INDOORS, tr_at(), and calendar::turn.

Referenced by actualize().

◆ find_clear_path()

std::vector< tripoint > map::find_clear_path ( const tripoint source,
const tripoint destination 
) const

Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one.

returns the line found, which may be the straight line, but blocked.

Definition at line 6372 of file map.cpp.

6374{
6375 // TODO: Push this junk down into the Bresenham method, it's already doing it.
6376 const point d( destination.xy() - source.xy() );
6377 const point a( std::abs( d.x ) * 2, std::abs( d.y ) * 2 );
6378 const int dominant = std::max( a.x, a.y );
6379 const int minor = std::min( a.x, a.y );
6380 // This seems to be the method for finding the ideal start value for the error value.
6381 const int ideal_start_offset = minor - dominant / 2;
6382 const int start_sign = ( ideal_start_offset > 0 ) - ( ideal_start_offset < 0 );
6383 // Not totally sure of the derivation.
6384 const int max_start_offset = std::abs( ideal_start_offset ) * 2 + 1;
6385 for( int horizontal_offset = -1; horizontal_offset <= max_start_offset; ++horizontal_offset ) {
6386 int candidate_offset = horizontal_offset * start_sign;
6387 if( sees( source, destination, rl_dist( source, destination ), candidate_offset ) ) {
6388 return line_to( source, destination, candidate_offset, 0 );
6389 }
6390 }
6391 // If we couldn't find a clear LoS, just return the ideal one.
6392 return line_to( source, destination, ideal_start_offset, 0 );
6393}
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6240

References a, line_to(), minor, rl_dist(), sees(), point::x, tripoint::xy(), and point::y.

Referenced by mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), find_target_vehicle(), mattack::flame(), projectile_attack(), mattack::ranged_pull(), target_ui::set_cursor_pos(), and ranged::targetable_creatures().

◆ find_furnitures_or_vparts_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_or_vparts_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures or vehicle parts with matching flag in the specified radius

Definition at line 8818 of file map.cpp.

8820{
8821 std::list<tripoint> locs;
8822 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8823 // workaround for ramp bridges
8824 int dz = 0;
8825 if( has_flag( TFLAG_RAMP_UP, loc ) ) {
8826 dz = 1;
8827 } else if( has_flag( TFLAG_RAMP_DOWN, loc ) ) {
8828 dz = -1;
8829 }
8830
8831 if( dz == 0 ) {
8832 if( has_flag_furn_or_vpart( flag, loc ) ) {
8833 locs.push_back( loc );
8834 }
8835 } else {
8836 const tripoint newloc( loc + tripoint( 0, 0, dz ) );
8837 if( has_flag_furn_or_vpart( flag, newloc ) ) {
8838 locs.push_back( newloc );
8839 }
8840 }
8841 }
8842
8843 return locs;
8844}
bool has_flag_furn_or_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2438

References center, has_flag(), has_flag_furn_or_vpart(), points_in_radius(), TFLAG_RAMP_DOWN, and TFLAG_RAMP_UP.

Referenced by activity_handlers::operation_do_turn(), activity_handlers::operation_finish(), and player_on_couch().

◆ find_furnitures_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures with matching flag in the specified radius

Definition at line 8804 of file map.cpp.

8808{
8809 std::list<tripoint> furn_locs;
8810 for( const auto &furn_loc : points_in_radius( center, radius, radiusz ) ) {
8811 if( has_flag_furn( flag, furn_loc ) ) {
8812 furn_locs.push_back( furn_loc );
8813 }
8814 }
8815 return furn_locs;
8816}

References center, has_flag_furn(), and points_in_radius().

◆ flammable_items_at()

bool map::flammable_items_at ( const tripoint p,
int  threshold = 0 
)

Checks if there are any flammable items on the tile.

Parameters
ptile to check
thresholdFuel threshold (lower means worse fuels are accepted).

Definition at line 2686 of file map.cpp.

2687{
2688 if( !has_items( p ) ||
2690 // Sealed containers don't allow fire, so shouldn't allow setting the fire either
2691 return false;
2692 }
2693
2694 for( const auto &i : i_at( p ) ) {
2695 if( i.flammable( threshold ) ) {
2696 return true;
2697 }
2698 }
2699
2700 return false;
2701}
@ TFLAG_ALLOW_FIELD_EFFECT
Definition: mapdata.h:286

References has_flag(), has_items(), i_at(), TFLAG_ALLOW_FIELD_EFFECT, and TFLAG_SEALED.

Referenced by MapExtras::burned_ground_parser(), is_flammable(), firestarter_actor::moves_cost_by_fuel(), process_fields_in_submap(), and item::process_litcig().

◆ floor_between()

bool map::floor_between ( const tripoint first,
const tripoint second 
) const

Checks if there's a floor between the two tiles.

They must be at most 1 tile away from each other in any dimension. If they're not at the same xy coord there must be floor on both of the relevant tiles

Definition at line 2084 of file map.cpp.

2085{
2086 int diff = std::abs( first.z - second.z );
2087 if( diff == 0 ) { //There's never a floor between two tiles on the same level
2088 return false;
2089 }
2090 if( diff != 1 ) {
2091 debugmsg( "map::floor_between should only be called on tiles that are exactly 1 z level apart" );
2092 return true;
2093 }
2094 int upper = std::max( first.z, second.z );
2095 if( first.xy() == second.xy() ) {
2096 return has_floor( tripoint( first.xy(), upper ) );
2097 }
2098 return has_floor( tripoint( first.xy(), upper ) ) && has_floor( tripoint( second.xy(), upper ) );
2099}

References debugmsg, has_floor(), second, tripoint::xy(), and tripoint::z.

Referenced by find_target_vehicle().

◆ free_volume()

units::volume map::free_volume ( const tripoint p)

Definition at line 4327 of file map.cpp.

4328{
4329 return i_at( p ).free_volume();
4330}
units::volume free_volume() const
Definition: item_stack.cpp:141

References item_stack::free_volume(), and i_at().

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), and advanced_inv_area::free_volume().

◆ function_over()

template<typename Functor >
void map::function_over ( const tripoint start,
const tripoint end,
Functor  fun 
) const
private

Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time.

gp in the functor is Grid (like get_submap_at_grid) coordinate of the submap, Will silently clip the area to map bounds.

Parameters
startStarting point for function
endEnd point for function
funFunction to run

Definition at line 8618 of file map.cpp.

8619{
8620 // start and end are just two points, end can be "before" start
8621 // Also clip the area to map area
8622 const tripoint min( std::max( std::min( start.x, end.x ), 0 ), std::max( std::min( start.y, end.y ),
8623 0 ), std::max( std::min( start.z, end.z ), -OVERMAP_DEPTH ) );
8624 const tripoint max( std::min( std::max( start.x, end.x ), SEEX * my_MAPSIZE - 1 ),
8625 std::min( std::max( start.y, end.y ), SEEY * my_MAPSIZE - 1 ), std::min( std::max( start.z, end.z ),
8626 OVERMAP_HEIGHT ) );
8627
8628 // Submaps that contain the bounding points
8629 const point min_sm( min.x / SEEX, min.y / SEEY );
8630 const point max_sm( max.x / SEEX, max.y / SEEY );
8631 // Z outermost, because submaps are flat
8632 tripoint gp;
8633 int &z = gp.z;
8634 int &smx = gp.x;
8635 int &smy = gp.y;
8636 for( z = min.z; z <= max.z; z++ ) {
8637 for( smx = min_sm.x; smx <= max_sm.x; smx++ ) {
8638 for( smy = min_sm.y; smy <= max_sm.y; smy++ ) {
8639 submap const *cur_submap = get_submap_at_grid( { smx, smy, z } );
8640 // Bounds on the submap coordinates
8641 const point sm_min( smx > min_sm.x ? 0 : min.x % SEEX, smy > min_sm.y ? 0 : min.y % SEEY );
8642 const point sm_max( smx < max_sm.x ? SEEX - 1 : max.x % SEEX,
8643 smy < max_sm.y ? SEEY - 1 : max.y % SEEY );
8644
8645 point lp;
8646 int &sx = lp.x;
8647 int &sy = lp.y;
8648 for( sx = sm_min.x; sx <= sm_max.x; ++sx ) {
8649 for( sy = sm_min.y; sy <= sm_max.y; ++sy ) {
8650 const iteration_state rval = fun( gp, cur_submap, lp );
8651 if( rval != ITER_CONTINUE ) {
8652 switch( rval ) {
8653 case ITER_SKIP_ZLEVEL:
8654 smx = my_MAPSIZE + 1;
8655 smy = my_MAPSIZE + 1;
8656 // Fall through
8657 case ITER_SKIP_SUBMAP:
8658 sx = SEEX;
8659 sy = SEEY;
8660 break;
8661 default:
8662 return;
8663 }
8664 }
8665 }
8666 }
8667 }
8668 }
8669 }
8670}
iteration_state
Enum used by functors in function_over to control execution.
Definition: map.h:1928

References get_submap_at_grid(), ITER_CONTINUE, ITER_SKIP_SUBMAP, ITER_SKIP_ZLEVEL, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, sx, sy, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by scent_blockers().

◆ furn() [1/2]

furn_id map::furn ( const tripoint p) const

Definition at line 1412 of file map.cpp.

1413{
1414 if( !inbounds( p ) ) {
1415 return f_null;
1416 }
1417
1418 point l;
1419 submap *const current_submap = get_submap_at( p, l );
1420
1421 return current_submap->get_furn( l );
1422}
furn_id get_furn(point p) const
Definition: submap.h:86

References f_null, submap::get_furn(), get_submap_at(), and inbounds().

Referenced by computer_session::action_blood_anal(), computer_session::action_sample(), actualize(), ter_furn_transform::add_all_messages(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), board_up(), MapExtras::burned_ground_parser(), can_construct(), can_examine_at(), can_move_furniture(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), deploy_tent_actor::check_intact(), activity_handlers::chop_tree_finish(), activity_handlers::clear_rubble_finish(), close_door(), doors::close_door(), coverage(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), destroy_furn(), displace_items_except_one_liquid(), game::do_turn(), construct::done_deconstruct(), editmap_hilight::draw(), draw_lab(), editmap::draw_main_ui_overlay(), drop_furniture(), Character::env_surgery_bonus(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_blood(), farm_action(), feature< furn_id >(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), find_base_construction(), find_potential_computer_point(), iexamine::fireplace(), Character::floor_bedding_warmth(), inventory::form_from_map(), furn(), furn_is_supported(), furnname(), generic_multi_activity_locations(), get_changed_ids_from_update(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_furn_transforms_into(), get_hack_type(), get_harvest(), get_harvest_names(), get_keg_capacity(), grab(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), has_adjacent_furniture_with(), has_flag_furn(), has_furn(), has_pre_terrain(), is_bashable(), is_bashable_furn(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), map_stack::max_volume(), mill_activate(), iexamine::mill_finalize(), mill_load_food(), avatar_action::move(), move_cost(), obstacle_coverage(), om_harvest_furn(), iexamine::on_smoke_out(), open_door(), activity_handlers::oxytorch_finish(), tutorial_game::per_turn(), Character::place_corpse(), game::place_player(), mission_start::place_priest_diary(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), game::print_terrain_info(), item::process_fake_mill(), item::process_fake_smoke(), iexamine::quern_examine(), rad_scorch(), iexamine::reload_furniture(), resolve_regional_terrain_and_furniture(), set_item_map_or_vehicle(), smash(), smoker_activate(), smoker_finalize(), smoker_load_food(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_furn_transform::transform(), avatar_funcs::try_to_sleep(), editmap::update_view_with_help(), pick_lock_actor::use(), use_charges(), iexamine::use_furn_fake_item(), game::walk_move(), water_from(), and workbench_crafting_speed_multiplier().

◆ furn() [2/2]

furn_id map::furn ( point  p) const
inline

Definition at line 793 of file map.h.

793 {
794 return furn( tripoint( p, abs_sub.z ) );
795 }

References abs_sub, furn(), and tripoint::z.

◆ furn_set() [1/2]

void map::furn_set ( const tripoint p,
const furn_id new_furniture,
cata::poly_serialized< active_tile_data new_active = nullptr 
)

Sets the furniture at given position.

Parameters
pPosition within the map
new_furnitureId of new furniture
new_activeOverride default active tile of new furniture

Definition at line 1424 of file map.cpp.

1426{
1427 if( !inbounds( p ) ) {
1428 return;
1429 }
1430
1431 point l;
1432 submap *const current_submap = get_submap_at( p, l );
1433 const furn_id old_id = current_submap->get_furn( l );
1434 if( old_id == new_furniture ) {
1435 // Nothing changed
1436 return;
1437 }
1438
1439 current_submap->set_furn( l, new_furniture );
1440
1441 // Set the dirty flags
1442 const furn_t &old_t = old_id.obj();
1443 const furn_t &new_t = new_furniture.obj();
1444
1445 // If player has grabbed this furniture and it's no longer grabbable, release the grab.
1446 if( g->u.get_grab_type() == OBJECT_FURNITURE && g->u.grab_point == p && !new_t.is_movable() ) {
1447 add_msg( _( "The %s you were grabbing is destroyed!" ), old_t.name() );
1448 g->u.grab( OBJECT_NONE );
1449 }
1450 // If a creature was crushed under a rubble -> free it
1451 if( old_id == f_rubble && new_furniture == f_null ) {
1452 Creature *c = g->critter_at( p );
1453 if( c ) {
1454 c->remove_effect( effect_crushed );
1455 }
1456 }
1457 if( new_t.has_flag( "EMITTER" ) ) {
1458 field_furn_locs.push_back( p );
1459 }
1460 if( old_t.transparent != new_t.transparent ) {
1463 }
1464
1465 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1467 }
1468
1469 if( old_t.has_flag( TFLAG_NO_FLOOR ) != new_t.has_flag( TFLAG_NO_FLOOR ) ) {
1472 }
1473
1474 if( old_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) != new_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) ) {
1475 set_floor_cache_dirty( p.z + 1 );
1476 }
1477
1479
1481
1482 // TODO: Limit to changes that affect move cost, traps and stairs
1484
1485 // Make sure the furniture falls if it needs to
1486 support_dirty( p );
1487 tripoint above( p.xy(), p.z + 1 );
1488 // Make sure that if we supported something and no longer do so, it falls down
1489 support_dirty( above );
1490
1491 if( old_t.active ) {
1492 current_submap->active_furniture.erase( point_sm_ms( l ) );
1493 // TODO: Only for g->m? Observer pattern?
1495 }
1496 if( new_t.active || new_active ) {
1498 if( new_active ) {
1499 atd = new_active;
1500 } else {
1501 atd = new_t.active->clone();
1502 atd->set_last_updated( calendar::turn );
1503 }
1504 current_submap->active_furniture[point_sm_ms( l )] = atd;
1506 }
1507}
Copyable unique_ptr that writes and reads objects of derived types.
void on_changed(const tripoint_abs_ms &p)
Updates grid at given global map square coordinate.
void set_floor_cache_dirty(const int zlev)
Definition: map.cpp:235
void set_memory_seen_cache_dirty(const tripoint &p)
Definition: map.cpp:8952
std::map< point_sm_ms, cata::poly_serialized< active_tile_data > > active_furniture
Definition: submap.h:221
void set_furn(point p, furn_id furn)
Definition: submap.h:90
coords::coord_point< point, coords::origin::submap, coords::ms > point_sm_ms
Definition: coordinates.h:473
coords::coord_point< tripoint, coords::origin::abs, coords::ms > tripoint_abs_ms
Definition: coordinates.h:486
distribution_grid_tracker & get_distribution_grid_tracker()
Returns distribution grid tracker that is a part of the global game *g.
Definition: game.cpp:12052
@ OBJECT_NONE
Definition: enums.h:187
@ OBJECT_FURNITURE
Definition: enums.h:197
bool is_movable() const
Definition: mapdata.cpp:1523
cata::poly_serialized< active_tile_data > active
Definition: mapdata.h:523
std::string name() const
Definition: mapdata.cpp:513

References _, furn_t::active, submap::active_furniture, add_msg(), c, effect_crushed, f_null, f_rubble, field_furn_locs, g, get_distribution_grid_tracker(), submap::get_furn(), get_submap_at(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), furn_t::is_movable(), map_data_common_t::name(), int_id< T >::obj(), OBJECT_FURNITURE, OBJECT_NONE, distribution_grid_tracker::on_changed(), set_floor_cache_dirty(), submap::set_furn(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, map_data_common_t::transparent, calendar::turn, tripoint::xy(), and tripoint::z.

Referenced by iexamine::aggie_plant(), grid_furn_transform_queue::apply(), jmapgen_sign::apply(), jmapgen_vending_machine::apply(), jmapgen_toilet::apply(), jmapgen_gaspump::apply(), jmapgen_furniture::apply(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_sealed_item::apply(), jmapgen_setmap::apply(), apply< furn_t >(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::clear_rubble_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), activity_handlers::cracking_finish(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), displace_items_except_one_liquid(), construct::done_deconstruct(), draw_circle_furn(), draw_lab(), draw_line_furn(), draw_rough_circle_furn(), draw_square_furn(), drop_furniture(), iexamine::egg_sack_generic(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), dig_activity_actor::finish(), hacking_activity_actor::finish(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), iexamine::fungus(), furn_set(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_furn(), iexamine::harvest_furn_nectar(), iexamine::harvest_plant(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), make_rubble(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_lake_shore(), mapgen_tutorial(), iexamine::migo_nerve_cluster(), mill_activate(), iexamine::mill_finalize(), MapExtras::mx_burned_ground(), MapExtras::mx_clay_deposit(), MapExtras::mx_grave(), MapExtras::mx_house_spider(), MapExtras::mx_minefield(), MapExtras::mx_pond(), MapExtras::mx_roadworks(), MapExtras::mx_spider(), MapExtras::mx_supplydrop(), om_harvest_furn(), open_door(), iexamine::open_safe(), activity_handlers::oxytorch_finish(), place_toilet(), place_vending(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), process_fields_in_submap(), iexamine::quern_examine(), rad_scorch(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), iexamine::safe(), science_room(), set(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_furn_transform::transform(), deploy_furn_actor::use(), deploy_tent_actor::use(), and game::vertical_move().

◆ furn_set() [2/2]

void map::furn_set ( point  p,
const furn_id new_furniture 
)
inline

Definition at line 805 of file map.h.

805 {
806 furn_set( tripoint( p, abs_sub.z ), new_furniture );
807 }

References abs_sub, furn_set(), and tripoint::z.

◆ furnname() [1/2]

std::string map::furnname ( const tripoint p)

Definition at line 1533 of file map.cpp.

1534{
1535 const furn_t &f = furn( p ).obj();
1536 if( f.has_flag( "PLANT" ) ) {
1537 // Can't use item_stack::only_item() since there might be fertilizer
1538 map_stack items = i_at( p );
1539 const map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
1540 return it.is_seed();
1541 } );
1542 if( seed == items.end() ) {
1543 debugmsg( "Missing seed for plant at (%d, %d, %d)", p.x, p.y, p.z );
1544 return "null";
1545 }
1546 const std::string &plant = seed->get_plant_name();
1547 return string_format( "%s (%s)", f.name(), plant );
1548 } else {
1549 return f.name();
1550 }
1551}
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
Definition: map.h:105
int seed(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:6008

References item_stack::begin(), debugmsg, item_stack::end(), furn(), map_data_common_t::has_flag(), i_at(), map_data_common_t::name(), int_id< T >::obj(), plant, iuse::seed(), string_format(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_lock_picking_tool(), apply_prying_tool(), vehicle::check_heli_ascend(), activity_handlers::clear_rubble_finish(), iexamine::egg_sack_generic(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), iexamine::fungus(), furnname(), grab(), harvest_common(), iexamine::locked_object(), iexamine::locked_object_pickable(), name(), game::place_player(), game::print_terrain_info(), iexamine::reload_furniture(), iexamine::rubble(), smash(), and deploy_tent_actor::use().

◆ furnname() [2/2]

std::string map::furnname ( point  p)
inline

Definition at line 809 of file map.h.

809 {
810 return furnname( tripoint( p, abs_sub.z ) );
811 }
std::string furnname(const tripoint &p)
Definition: map.cpp:1533

References abs_sub, furnname(), and tripoint::z.

◆ gas_can_spread_to()

bool map::gas_can_spread_to ( field_entry cur,
const tripoint src,
const tripoint dst 
)
private

Definition at line 211 of file map_field.cpp.

212{
213 maptile dst_tile = maptile_at( dst );
214 const field_entry *tmpfld = dst_tile.get_field().find_field( cur.get_field_type() );
215 // Candidates are existing weaker fields or navigable/flagged tiles with no field.
216 if( tmpfld == nullptr || tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
217 const ter_t &ter = dst_tile.get_ter_t();
218 const furn_t &frn = dst_tile.get_furn_t();
219 return !obstructed_by_vehicle_rotation( src, dst ) &&
220 ( ter_furn_movecost( ter, frn ) > 0 || ter_furn_has_flag( ter, frn, TFLAG_PERMEABLE ) );
221 }
222 return false;
223}
bool ter_furn_has_flag(const ter_t &ter, const furn_t &furn, const ter_bitflags flag)
Definition: map_field.cpp:161
static int ter_furn_movecost(const ter_t &ter, const furn_t &furn)
Definition: map_field.cpp:166
@ TFLAG_PERMEABLE
Definition: mapdata.h:304
const ter_t & get_ter_t() const
Definition: submap.h:271
const field & get_field() const
Definition: submap.h:275
const furn_t & get_furn_t() const
Definition: submap.h:268

References field::find_field(), maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_ter_t(), maptile_at(), obstructed_by_vehicle_rotation(), ter(), ter_furn_has_flag(), ter_furn_movecost(), and TFLAG_PERMEABLE.

Referenced by spread_gas().

◆ gas_spread_to()

void map::gas_spread_to ( field_entry cur,
maptile dst,
const tripoint p 
)
private

Definition at line 225 of file map_field.cpp.

226{
227 const field_type_id current_type = cur.get_field_type();
228 const time_duration current_age = cur.get_field_age();
229 const int current_intensity = cur.get_field_intensity();
230 field_entry *f = dst.find_field( current_type );
231 // Nearby gas grows thicker, and ages are shared.
232 const time_duration age_fraction = current_age / current_intensity;
233 if( f != nullptr ) {
235 cur.set_field_intensity( current_intensity - 1 );
236 f->set_field_age( f->get_field_age() + age_fraction );
237 cur.set_field_age( current_age - age_fraction );
238 // Or, just create a new field.
239 } else if( add_field( p, current_type, 1, 0_turns ) ) {
240 f = dst.find_field( current_type );
241 if( f != nullptr ) {
242 f->set_field_age( age_fraction );
243 } else {
244 debugmsg( "While spreading the gas, field was added but doesn't exist." );
245 }
246 cur.set_field_intensity( current_intensity - 1 );
247 cur.set_field_age( current_age - age_fraction );
248 }
249}
int set_field_intensity(int new_intensity)
Definition: field.cpp:126
field_entry * find_field(const field_type_id &field_to_find)
Definition: submap.h:279

References add_field(), debugmsg, maptile::find_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_entry::set_field_age(), and field_entry::set_field_intensity().

Referenced by spread_gas().

◆ generate()

void map::generate ( const tripoint p,
const time_point when 
)

Definition at line 107 of file mapgen.cpp.

108{
109 dbg( DL::Info ) << "map::generate( g[" << g.get() << "], p[" << p <<
110 "], when[" << to_string( when ) << "] )";
111
112 set_abs_sub( p );
113
114 // First we have to create new submaps and initialize them to 0 all over
115 // We create all the submaps, even if we're not a tinymap, so that map
116 // generation which overflows won't cause a crash. At the bottom of this
117 // function, we save the upper-left 4 submaps, and delete the rest.
118 // Mapgen is not z-level aware yet. Only actually initialize current z-level
119 // because other submaps won't be touched.
120 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
121 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
122 const size_t grid_pos = get_nonant( { gridx, gridy, p.z } );
123 if( getsubmap( grid_pos ) ) {
124 debugmsg( "Submap already exists at (%d, %d, %d)", gridx, gridy, p.z );
125 continue;
126 }
127 setsubmap( grid_pos, new submap() );
128 // TODO: memory leak if the code below throws before the submaps get stored/deleted!
129 }
130 }
131 // x, and y are submap coordinates, convert to overmap terrain coordinates
132 // TODO: fix point types
133 tripoint_abs_omt abs_omt( sm_to_omt_copy( p ) );
134 oter_id terrain_type = overmap_buffer.ter( abs_omt );
135
136 // This attempts to scale density of zombies inversely with distance from the nearest city.
137 // In other words, make city centers dense and perimeters sparse.
138 float density = 0.0;
139 for( int i = -MON_RADIUS; i <= MON_RADIUS; i++ ) {
140 for( int j = -MON_RADIUS; j <= MON_RADIUS; j++ ) {
141 density += overmap_buffer.ter( abs_omt + point( i, j ) )->get_mondensity();
142 }
143 }
144 density = density / 100;
145
146 mapgendata dat( abs_omt, *this, density, when, nullptr );
147 draw_map( dat );
148
149 // At some point, we should add region information so we can grab the appropriate extras
150 map_extras ex = region_settings_map["default"].region_extras[terrain_type->get_extras()];
151 if( ex.chance > 0 && one_in( ex.chance ) ) {
152 std::string *extra = ex.values.pick();
153 if( extra == nullptr ) {
154 debugmsg( "failed to pick extra for type %s", terrain_type->get_extras() );
155 } else {
156 MapExtras::apply_function( *( ex.values.pick() ), *this, abs_sub );
157 }
158 }
159
160 const auto &spawns = terrain_type->get_static_spawns();
161
162 float spawn_density = 1.0f;
163 if( MonsterGroupManager::is_animal( spawns.group ) ) {
164 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
165 } else {
166 spawn_density = get_option< float >( "SPAWN_DENSITY" );
167 }
168
169 // Apply a multiplier to the number of monsters for really high densities.
170 float odds_after_density = spawns.chance * spawn_density;
171 const float max_odds = 100 - ( 100 - spawns.chance ) / 2.0;
172 float density_multiplier = 1.0f;
173 if( odds_after_density > max_odds ) {
174 density_multiplier = 1.0f * odds_after_density / max_odds;
175 odds_after_density = max_odds;
176 }
177 const int spawn_count = roll_remainder( density_multiplier );
178
179 if( spawns.group && x_in_y( odds_after_density, 100 ) ) {
180 int pop = spawn_count * rng( spawns.population.min, spawns.population.max );
181 for( ; pop > 0; pop-- ) {
182 MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( spawns.group, &pop );
183 if( !spawn_details.name ) {
184 continue;
185 }
186 if( const std::optional<tripoint> pt =
187 random_point( *this, [this]( const tripoint & n ) {
188 return passable( n );
189 } ) ) {
190 add_spawn( spawn_details.name, spawn_details.pack_size, *pt );
191 }
192 }
193 }
194
195 // Okay, we know who are neighbors are. Let's draw!
196 // And finally save used submaps and delete the rest.
197 for( int i = 0; i < my_MAPSIZE; i++ ) {
198 for( int j = 0; j < my_MAPSIZE; j++ ) {
199 dbg( DL::Info ) << "map::generate: submap (" << i << "," << j << ")";
200
201 const tripoint pos( i, j, p.z );
202 if( i <= 1 && j <= 1 ) {
203 saven( pos );
204 } else {
205 const size_t grid_pos = get_nonant( pos );
206 delete getsubmap( grid_pos );
207 setsubmap( grid_pos, nullptr );
208 }
209 }
210 }
211}
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
static bool is_animal(const mongroup_id &group)
Definition: mongroup.cpp:401
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void saven(const tripoint &grid)
Definition: map.cpp:7048
void set_abs_sub(const tripoint &p)
Sets abs_sub, see there.
Definition: map.cpp:8398
void draw_map(mapgendata &dat)
Definition: mapgen.cpp:2913
submap * getsubmap(size_t grididx) const
Get the submap pointer with given index in grid, the index must be valid!
Definition: map.cpp:8408
void add_spawn(const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
Definition: mapgen.cpp:5611
bool passable(const tripoint &p) const
Definition: map.cpp:1864
Contains various information regarding the individual mapgen instance (generating a specific part of ...
Definition: mapgendata.h:36
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
point sm_to_omt_copy(point p)
static constexpr int MON_RADIUS
Definition: mapgen.cpp:101
void apply_function(const string_id< map_extra > &id, map &m, const tripoint &abs_sub)
t_regional_settings_map region_settings_map
Definition: overmap.cpp:186
mtype_id name
Definition: mongroup.h:53
unsigned int chance
weighted_int_list< std::string > values
const std::string & get_extras() const
Definition: omdata.h:237
const overmap_static_spawns & get_static_spawns() const
Definition: omdata.h:245
int get_mondensity() const
Definition: omdata.h:241

References abs_sub, add_spawn(), MapExtras::apply_function(), map_extras::chance, dbg, debugmsg, draw_map(), g, oter_t::get_extras(), oter_t::get_mondensity(), get_nonant(), oter_t::get_static_spawns(), MonsterGroupManager::GetResultFromGroup(), getsubmap(), Info, MonsterGroupManager::is_animal(), MON_RADIUS, my_MAPSIZE, MonsterGroupResult::name, one_in(), overmap_buffer, MonsterGroupResult::pack_size, passable(), random_point(), region_settings_map, rng(), roll_remainder(), saven(), set_abs_sub(), setsubmap(), sm_to_omt_copy(), overmapbuffer::ter(), to_string(), map_extras::values, x_in_y(), and tripoint::z.

Referenced by farm_action(), defense_game::init_map(), loadn(), and editmap::mapgen_preview().

◆ generate_lightmap()

void map::generate_lightmap ( int  zlev)
protected

Definition at line 435 of file lightmap.cpp.

436{
437 auto &map_cache = get_cache( zlev );
438 auto &lm = map_cache.lm;
439 auto &sm = map_cache.sm;
440 auto &outside_cache = map_cache.outside_cache;
441 auto &prev_floor_cache = get_cache( clamp( zlev + 1, -OVERMAP_DEPTH, OVERMAP_DEPTH ) ).floor_cache;
442 bool top_floor = zlev == OVERMAP_DEPTH;
443 std::memset( lm, 0, sizeof( lm ) );
444 std::memset( sm, 0, sizeof( sm ) );
445
446 /* Bulk light sources wastefully cast rays into neighbors; a burning hospital can produce
447 significant slowdown, so for stuff like fire and lava:
448 * Step 1: Store the position and luminance in buffer via add_light_source, for efficient
449 checking of neighbors.
450 * Step 2: After everything else, iterate buffer and apply_light_source only in non-redundant
451 directions
452 * Step 3: ????
453 * Step 4: Profit!
454 */
455 auto &light_source_buffer = map_cache.light_source_buffer;
456 std::memset( light_source_buffer, 0, sizeof( light_source_buffer ) );
457
458 constexpr std::array<int, 4> dir_x = { { 0, -1, 1, 0 } }; // [0]
459 constexpr std::array<int, 4> dir_y = { { -1, 0, 0, 1 } }; // [1][X][2]
460 constexpr std::array<int, 4> dir_d = { { 90, 0, 180, 270 } }; // [3]
461 constexpr std::array<std::array<quadrant, 2>, 4> dir_quadrants = { {
466 }
467 };
468
469 const float natural_light = g->natural_light_level( zlev );
470
471 build_sunlight_cache( zlev );
472
474 for( npc &guy : g->all_npcs() ) {
476 }
477
478 std::vector<std::pair<tripoint, float>> lm_override;
479 // Traverse the submaps in order
480 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
481 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
482 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
483
484 for( int sx = 0; sx < SEEX; ++sx ) {
485 for( int sy = 0; sy < SEEY; ++sy ) {
486 const int x = sx + smx * SEEX;
487 const int y = sy + smy * SEEY;
488 const tripoint p( x, y, zlev );
489 // Project light into any openings into buildings.
490 if( !outside_cache[p.x][p.y] || ( !top_floor && prev_floor_cache[p.x][p.y] ) ) {
491 // Apply light sources for external/internal divide
492 for( int i = 0; i < 4; ++i ) {
493 point neighbour = p.xy() + point( dir_x[i], dir_y[i] );
494 if( lightmap_boundaries.contains( neighbour )
495 && outside_cache[neighbour.x][neighbour.y] &&
496 ( top_floor || !prev_floor_cache[neighbour.x][neighbour.y] )
497 ) {
498 const float source_light =
499 std::min( natural_light, lm[neighbour.x][neighbour.y].max() );
501 update_light_quadrants( lm[p.x][p.y], source_light, quadrant::default_ );
502 apply_directional_light( p, dir_d[i], source_light );
503 } else {
504 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][0] );
505 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][1] );
506 }
507 }
508 }
509 }
510
511 if( cur_submap->get_lum( { sx, sy } ) && has_items( p ) ) {
512 auto items = i_at( p );
513 add_light_from_items( p, items.begin(), items.end() );
514 }
515
516 const ter_id terrain = cur_submap->get_ter( { sx, sy } );
517 if( terrain->light_emitted > 0 ) {
518 add_light_source( p, terrain->light_emitted );
519 }
520 const furn_id furniture = cur_submap->get_furn( {sx, sy } );
521 if( furniture->light_emitted > 0 ) {
522 add_light_source( p, furniture->light_emitted );
523 }
524
525 for( auto &fld : cur_submap->get_field( { sx, sy } ) ) {
526 const field_entry *cur = &fld.second;
527 const int light_emitted = cur->light_emitted();
528 if( light_emitted > 0 ) {
529 add_light_source( p, light_emitted );
530 }
531 const float light_override = cur->local_light_override();
532 if( light_override >= 0.0 ) {
533 lm_override.push_back( std::pair<tripoint, float>( p, light_override ) );
534 }
535 }
536 }
537 }
538 }
539 }
540
541 for( monster &critter : g->all_monsters() ) {
542 if( critter.is_hallucination() ) {
543 continue;
544 }
545 const tripoint &mp = critter.pos();
546 if( inbounds( mp ) ) {
547 if( critter.has_effect( effect_onfire ) ) {
548 apply_light_source( mp, 8 );
549 }
550 // TODO: [lightmap] Attach natural light brightness to creatures
551 // TODO: [lightmap] Allow creatures to have light attacks (i.e.: eyebot)
552 // TODO: [lightmap] Allow creatures to have facing and arc lights
553 if( critter.type->luminance > 0 ) {
554 apply_light_source( mp, critter.type->luminance );
555 }
556 }
557 }
558
559 // Apply any vehicle light sources
560 VehicleList vehs = get_vehicles();
561 for( auto &vv : vehs ) {
562 vehicle *v = vv.v;
563
564 auto lights = v->lights( true );
565
566 float veh_luminance = 0.0;
567 float iteration = 1.0;
568
569 for( const auto pt : lights ) {
570 const auto &vp = pt->info();
571 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ||
572 vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
573 veh_luminance += vp.bonus / iteration;
574 iteration = iteration * 1.1;
575 }
576 }
577
578 for( const auto pt : lights ) {
579 const auto &vp = pt->info();
580 tripoint src = v->global_part_pos3( *pt );
581
582 if( !inbounds( src ) ) {
583 continue;
584 }
585
586 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ) {
587 if( veh_luminance > lit_level::LIT ) {
588 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
589 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
590 45_degrees );
591 }
592
593 } else if( vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
594 if( veh_luminance > lit_level::LIT ) {
595 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
596 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
597 90_degrees );
598 }
599
600 } else if( vp.has_flag( VPFLAG_HALF_CIRCLE_LIGHT ) ) {
601 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
602 apply_light_arc( src, v->face.dir() + pt->direction, vp.bonus, 180_degrees );
603
604 } else if( vp.has_flag( VPFLAG_CIRCLE_LIGHT ) ) {
605 const bool odd_turn = calendar::once_every( 2_turns );
606 if( ( odd_turn && vp.has_flag( VPFLAG_ODDTURN ) ) ||
607 ( !odd_turn && vp.has_flag( VPFLAG_EVENTURN ) ) ||
608 ( !( vp.has_flag( VPFLAG_EVENTURN ) || vp.has_flag( VPFLAG_ODDTURN ) ) ) ) {
609
610 add_light_source( src, vp.bonus );
611 }
612
613 } else {
614 add_light_source( src, vp.bonus );
615 }
616 }
617
618 for( const vpart_reference &vp : v->get_all_parts() ) {
619 const size_t p = vp.part_index();
620 const tripoint pp = vp.pos();
621 if( !inbounds( pp ) ) {
622 continue;
623 }
624 if( vp.has_feature( VPFLAG_CARGO ) && !vp.has_feature( "COVERED" ) ) {
625 add_light_from_items( pp, v->get_items( static_cast<int>( p ) ).begin(),
626 v->get_items( static_cast<int>( p ) ).end() );
627 }
628 }
629 }
630
631 /* Now that we have position and intensity of all bulk light sources, apply_ them
632 This may seem like extra work, but take a 12x12 raging inferno:
633 unbuffered: (12^2)*(160*4) = apply_light_ray x 92160
634 buffered: (12*4)*(160) = apply_light_ray x 7680
635 */
636 const tripoint cache_start( 0, 0, zlev );
637 const tripoint cache_end( LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, zlev );
638 for( const tripoint &p : points_in_rectangle( cache_start, cache_end ) ) {
639 if( light_source_buffer[p.x][p.y] > 0.0 ) {
640 apply_light_source( p, light_source_buffer[p.x][p.y] );
641 }
642 }
643 for( const std::pair<tripoint, float> &elem : lm_override ) {
644 lm[elem.first.x][elem.first.y].fill( elem.second );
645 }
646}
float light_emitted() const
Definition: field.cpp:69
float local_light_override() const
Definition: field.cpp:74
float light_transparency(const tripoint &p) const
Definition: lightmap.cpp:695
void apply_directional_light(const tripoint &p, int direction, float luminance)
Definition: lightmap.cpp:1830
void build_sunlight_cache(int pzlev)
Definition: lightmap.cpp:284
void add_light_from_items(const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
Definition: lightmap.cpp:86
void apply_character_light(Character &p)
Definition: lightmap.cpp:262
Definition: npc.h:744
units::angle dir() const
Definition: tileray.cpp:74
std::vector< vehicle_part * > lights(bool active=false)
Get all vehicle lights (excluding any that are destroyed)
Definition: vehicle.cpp:4644
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5470
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
@ VPFLAG_CONE_LIGHT
Definition: veh_type.h:35
@ VPFLAG_CIRCLE_LIGHT
Definition: veh_type.h:38
@ VPFLAG_CARGO
Definition: veh_type.h:62
@ VPFLAG_EVENTURN
Definition: veh_type.h:33
@ VPFLAG_WIDE_CONE_LIGHT
Definition: veh_type.h:36
@ VPFLAG_ODDTURN
Definition: veh_type.h:34
@ VPFLAG_HALF_CIRCLE_LIGHT
Definition: veh_type.h:37

References add_light_from_items(), add_light_source(), apply_character_light(), apply_directional_light(), apply_light_arc(), apply_light_source(), item_stack::begin(), build_sunlight_cache(), clamp(), default_, tileray::dir(), effect_onfire, item_stack::end(), vehicle::face, level_cache::floor_cache, furniture, g, vehicle::get_all_parts(), get_cache(), vehicle::get_items(), get_player_character(), get_submap_at_grid(), get_vehicles(), vehicle::global_part_pos3(), has_items(), i_at(), inbounds(), field_entry::light_emitted(), light_transparency(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, vehicle::lights(), LIT, field_entry::local_light_override(), M_SQRT2, my_MAPSIZE, NE, NW, calendar::once_every(), OVERMAP_DEPTH, points_in_rectangle(), SE, SEEX, SEEY, coords::sm, SW, sx, sy, terrain, update_light_quadrants(), VPFLAG_CARGO, VPFLAG_CIRCLE_LIGHT, VPFLAG_CONE_LIGHT, VPFLAG_EVENTURN, VPFLAG_HALF_CIRCLE_LIGHT, VPFLAG_ODDTURN, VPFLAG_WIDE_CONE_LIGHT, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by build_map_cache().

◆ get_abs_sub()

◆ get_active_items_in_radius() [1/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius 
) const

Definition at line 8758 of file map.cpp.

8760{
8762}
std::list< item_location > get_active_items_in_radius(const tripoint &center, int radius) const
Definition: map.cpp:8758

References center, get_active_items_in_radius(), and none.

Referenced by npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), and get_active_items_in_radius().

◆ get_active_items_in_radius() [2/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius,
special_item_type  type 
) const

Definition at line 8764 of file map.cpp.

8766{
8767 std::list<item_location> result;
8768
8769 const point minp( center.xy() + point( -radius, -radius ) );
8770 const point maxp( center.xy() + point( radius, radius ) );
8771
8772 const point ming( std::max( minp.x / SEEX, 0 ),
8773 std::max( minp.y / SEEY, 0 ) );
8774 const point maxg( std::min( maxp.x / SEEX, my_MAPSIZE - 1 ),
8775 std::min( maxp.y / SEEY, my_MAPSIZE - 1 ) );
8776
8777 for( const tripoint &abs_submap_loc : submaps_with_active_items ) {
8778 const tripoint submap_loc{ -abs_sub.xy() + abs_submap_loc };
8779 if( submap_loc.x < ming.x || submap_loc.y < ming.y ||
8780 submap_loc.x > maxg.x || submap_loc.y > maxg.y ) {
8781 continue;
8782 }
8783 const point sm_offset( submap_loc.x * SEEX, submap_loc.y * SEEY );
8784
8785 submap *sm = get_submap_at_grid( submap_loc );
8786 std::vector<item_reference> items = type == special_item_type::none ? sm->active_items.get() :
8787 sm->active_items.get_special( type );
8788 for( const auto &elem : items ) {
8789 const tripoint pos( sm_offset + elem.location, submap_loc.z );
8790
8791 if( rl_dist( pos, center ) > radius ) {
8792 continue;
8793 }
8794
8795 if( elem.item_ref ) {
8796 result.emplace_back( map_cursor( pos ), elem.item_ref.get() );
8797 }
8798 }
8799 }
8800
8801 return result;
8802}

References abs_sub, center, get_submap_at_grid(), my_MAPSIZE, none, rl_dist(), SEEX, SEEY, coords::sm, submaps_with_active_items, type, point::x, tripoint::xy(), and point::y.

◆ get_cache()

◆ get_cache_ref()

◆ get_creatures_in_radius()

std::list< Creature * > map::get_creatures_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
)

returns creatures in specified radius

Definition at line 8846 of file map.cpp.

8848{
8849 std::list<Creature *> creatures;
8850 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8851 Creature *tmp_critter = g->critter_at( loc );
8852 if( tmp_critter != nullptr ) {
8853 creatures.push_back( tmp_critter );
8854 }
8855
8856 }
8857 return creatures;
8858}

References center, g, and points_in_radius().

◆ get_dir_circle()

std::vector< tripoint > map::get_dir_circle ( const tripoint f,
const tripoint t 
) const

Calculate next search points surrounding the current position.

Points closer to the target come first. This method leads to straighter lines and prevents weird looking movements away from the target.

Definition at line 6671 of file map.cpp.

6672{
6673 std::vector<tripoint> circle;
6674 circle.resize( 8 );
6675
6676 // The line below can be crazy expensive - we only take the FIRST point of it
6677 const std::vector<tripoint> line = line_to( f, t, 0, 0 );
6678 const std::vector<tripoint> spiral = closest_points_first( f, 1 );
6679 const std::vector<int> pos_index {1, 2, 4, 6, 8, 7, 5, 3};
6680
6681 // All possible constellations (closest_points_first goes clockwise)
6682 // 753 531 312 124 246 468 687 875
6683 // 8 1 7 2 5 4 3 6 1 8 2 7 4 5 6 3
6684 // 642 864 786 578 357 135 213 421
6685
6686 size_t pos_offset = 0;
6687 for( size_t i = 1; i < spiral.size(); i++ ) {
6688 if( spiral[i] == line[0] ) {
6689 pos_offset = i - 1;
6690 break;
6691 }
6692 }
6693
6694 for( size_t i = 1; i < spiral.size(); i++ ) {
6695 if( pos_offset >= pos_index.size() ) {
6696 pos_offset = 0;
6697 }
6698
6699 circle[pos_index[pos_offset++] - 1] = spiral[i];
6700 }
6701
6702 return circle;
6703}
void circle(map *m, const ter_id &type, double x, double y, double rad)
Definition: mapgen.cpp:6525

References circle(), closest_points_first(), line(), and line_to().

Referenced by npc::move_to().

◆ get_field() [1/2]

field & map::get_field ( const tripoint p)
private

Definition at line 8594 of file map.cpp.

8595{
8596 return field_at( p );
8597}

References field_at().

◆ get_field() [2/2]

◆ get_field_age()

time_duration map::get_field_age ( const tripoint p,
const field_type_id type 
) const

Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns.

Definition at line 5471 of file map.cpp.

5472{
5473 auto field_ptr = field_at( p ).find_field( type );
5474 return field_ptr == nullptr ? -1_turns : field_ptr->get_field_age();
5475}

References field_at(), field::find_field(), field_entry::get_field_age(), and type.

Referenced by game::grabbed_furn_move(), try_fuel_fire(), and game::walk_move().

◆ get_field_intensity()

int map::get_field_intensity ( const tripoint p,
const field_type_id type 
) const

Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0.

Definition at line 5477 of file map.cpp.

5478{
5479 auto field_ptr = field_at( p ).find_field( type );
5480 return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() );
5481}

References field_at(), field::find_field(), and type.

Referenced by character_funcs::base_comfort_value(), game::grabbed_furn_move(), is_flammable(), propagate_field(), fungal_effects::spread_fungus_one_tile(), avatar_funcs::try_to_sleep(), and game::walk_move().

◆ get_furn_field_locations()

const std::vector< tripoint > & map::get_furn_field_locations ( ) const

Definition at line 7858 of file map.cpp.

7859{
7860 return field_furn_locs;
7861}

References field_furn_locs.

Referenced by game::do_turn().

◆ get_furn_transforms_into()

furn_id map::get_furn_transforms_into ( const tripoint p) const

Definition at line 1676 of file map.cpp.

1677{
1678 return furn( p ).obj().transforms_into.id();
1679}
furn_str_id transforms_into
Definition: mapdata.h:503

References furn(), string_id< T >::id(), int_id< T >::obj(), and furn_t::transforms_into.

◆ get_harvest()

const harvest_id & map::get_harvest ( const tripoint p) const

Returns the full harvest list, for spawning.

Definition at line 1628 of file map.cpp.

1629{
1630 const auto furn_here = furn( pos );
1631 if( furn_here->examine != iexamine::none ) {
1632 // Note: if furniture can be examined, the terrain can NOT (until furniture is removed)
1633 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1634 return harvest_id::NULL_ID();
1635 }
1636
1637 return furn_here->get_harvest();
1638 }
1639
1640 const auto ter_here = ter( pos );
1641 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1642 return harvest_id::NULL_ID();
1643 }
1644
1645 return ter_here->get_harvest();
1646}
static const string_id< harvest_list > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
@ TFLAG_HARVESTED
Definition: mapdata.h:303

References furn(), iexamine::none(), string_id< harvest_list >::NULL_ID(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by harvest_common(), and is_harvestable().

◆ get_harvest_names()

const std::set< std::string > & map::get_harvest_names ( const tripoint p) const

Returns names of the items that would be dropped.

Definition at line 1648 of file map.cpp.

1649{
1650 static const std::set<std::string> null_harvest_names = {};
1651 const auto furn_here = furn( pos );
1652 if( furn_here->examine != iexamine::none ) {
1653 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1654 return null_harvest_names;
1655 }
1656
1657 return furn_here->get_harvest_names();
1658 }
1659
1660 const auto ter_here = ter( pos );
1661 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1662 return null_harvest_names;
1663 }
1664
1665 return ter_here->get_harvest_names();
1666}

References furn(), iexamine::none(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by npc::find_item().

◆ get_known_connections()

uint8_t map::get_known_connections ( const tripoint p,
int  connect_group,
const std::map< tripoint, ter_id > &  override = {} 
) const

Definition at line 1574 of file map.cpp.

1576{
1577 auto &ch = access_cache( p.z );
1578 uint8_t val = 0;
1579 std::function<bool( const tripoint & )> is_memorized;
1580#ifdef TILES
1581 if( use_tiles ) {
1582 is_memorized =
1583 [&]( const tripoint & q ) {
1584 return !g->u.get_memorized_tile( getabs( q ) ).tile.empty();
1585 };
1586 } else {
1587#endif
1588 is_memorized =
1589 [&]( const tripoint & q ) {
1590 return g->u.get_memorized_symbol( getabs( q ) );
1591 };
1592#ifdef TILES
1593 }
1594#endif
1595
1596 const bool overridden = override.find( p ) != override.end();
1597 const bool is_transparent = ch.transparency_cache[p.x][p.y] > LIGHT_TRANSPARENCY_SOLID;
1598
1599 // populate connection information
1600 for( int i = 0; i < 4; ++i ) {
1601 tripoint neighbour = p + offsets[i];
1602 if( !inbounds( neighbour ) ) {
1603 continue;
1604 }
1605 const auto neighbour_override = override.find( neighbour );
1606 const bool neighbour_overridden = neighbour_override != override.end();
1607 // if there's some non-memory terrain to show at the neighboring tile
1608 const bool may_connect = neighbour_overridden ||
1609 get_visibility( ch.visibility_cache[neighbour.x][neighbour.y],
1611 // or if an actual center tile is transparent or next to a memorized tile
1612 ( !overridden && ( is_transparent || is_memorized( neighbour ) ) );
1613 if( may_connect ) {
1614 const ter_t &neighbour_terrain = neighbour_overridden ?
1615 neighbour_override->second.obj() : ter( neighbour ).obj();
1616 if( neighbour_terrain.connects_to( connect_group ) ) {
1617 val += 1 << i;
1618 }
1619 }
1620 }
1621
1622 return val;
1623}
bool use_tiles
Use tiles for display.
bool is_transparent(const tripoint &p) const
Returns whether the tile at p is transparent(you can look past it).
Definition: lightmap.cpp:690
level_cache & access_cache(int zlev)
Definition: map.cpp:8860
static constexpr std::array< point, 4 > offsets
Definition: point.h:361
bool connects_to(int test_connect_group) const
Definition: mapdata.h:435

References access_cache(), map_data_common_t::connects_to(), g, get_visibility(), get_visibility_variables_cache(), getabs(), inbounds(), is_transparent(), LIGHT_TRANSPARENCY_SOLID, int_id< T >::obj(), offsets, ter(), use_tiles, VIS_CLEAR, tripoint::x, tripoint::y, and tripoint::z.

Referenced by determine_wall_corner().

◆ get_neighbors()

std::array< std::pair< tripoint, maptile >, 8 > map::get_neighbors ( const tripoint p)
private

Definition at line 190 of file map_field.cpp.

191{
192 // Find out which edges are in the bubble
193 // Where possible, do just one bounds check for all the neighbors
194 const bool west = p.x > 0;
195 const bool north = p.y > 0;
196 const bool east = p.x < SEEX * my_MAPSIZE - 1;
197 const bool south = p.y < SEEY * my_MAPSIZE - 1;
198 return std::array< std::pair<tripoint, maptile>, 8 > { {
199 maptile_has_bounds( p + eight_horizontal_neighbors[0], west &&north ),
201 maptile_has_bounds( p + eight_horizontal_neighbors[2], east &&north ),
204 maptile_has_bounds( p + eight_horizontal_neighbors[5], west &&south ),
206 maptile_has_bounds( p + eight_horizontal_neighbors[7], east &&south ),
207 }
208 };
209}
std::pair< tripoint, maptile > maptile_has_bounds(const tripoint &p, bool bounds_checked)
Definition: map_field.cpp:180
static const std::array< tripoint, 8 > eight_horizontal_neighbors
Definition: point.h:379

References eight_horizontal_neighbors, maptile_has_bounds(), my_MAPSIZE, SEEX, SEEY, tripoint::x, and tripoint::y.

Referenced by process_fields_in_submap(), and spread_gas().

◆ get_nonant() [1/2]

size_t map::get_nonant ( const tripoint gridp) const
protected

Get the index of a submap pointer in the grid given by grid coordinates.

The grid coordinates must be valid: 0 <= x < my_MAPSIZE, same for y. Version with z-levels checks for z between -OVERMAP_DEPTH and OVERMAP_HEIGHT

Definition at line 8450 of file map.cpp.

8451{
8452 // There used to be a bounds check here
8453 // But this function is called a lot, so push it up if needed
8454 if( zlevels ) {
8455 const int indexz = gridp.z + OVERMAP_HEIGHT; // Can't be lower than 0
8456 return indexz + ( gridp.x + gridp.y * my_MAPSIZE ) * OVERMAP_LAYERS;
8457 } else {
8458 return gridp.x + gridp.y * my_MAPSIZE;
8459 }
8460}

References my_MAPSIZE, OVERMAP_HEIGHT, OVERMAP_LAYERS, tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by copy_grid(), fake_map::fake_map(), generate(), get_nonant(), get_submap_at_grid(), loadn(), and saven().

◆ get_nonant() [2/2]

size_t map::get_nonant ( point  gridp) const
inlineprotected

Definition at line 1842 of file map.h.

1842 {
1843 return get_nonant( { gridp, abs_sub.z } );
1844 }

References abs_sub, get_nonant(), and tripoint::z.

◆ get_pathfinding_cache()

pathfinding_cache & map::get_pathfinding_cache ( int  zlev) const
private

Definition at line 8910 of file map.cpp.

8911{
8912 return *pathfinding_caches[zlev + OVERMAP_DEPTH];
8913}

References OVERMAP_DEPTH, and pathfinding_caches.

Referenced by get_pathfinding_cache_ref(), set_pathfinding_cache_dirty(), and update_pathfinding_cache().

◆ get_pathfinding_cache_ref()

const pathfinding_cache & map::get_pathfinding_cache_ref ( int  zlev) const

Definition at line 8960 of file map.cpp.

8961{
8962 if( !inbounds_z( zlev ) ) {
8963 debugmsg( "Tried to get pathfinding cache for out of bounds z-level %d", zlev );
8965 }
8966 auto &cache = get_pathfinding_cache( zlev );
8967 if( cache.dirty ) {
8969 }
8970
8971 return cache;
8972}
void update_pathfinding_cache(int zlev) const
Definition: map.cpp:8974
bool inbounds_z(const int z) const
Definition: map.h:1623
pathfinding_cache & get_pathfinding_cache(int zlev) const
Definition: map.cpp:8910

References debugmsg, get_pathfinding_cache(), inbounds_z(), OVERMAP_DEPTH, pathfinding_caches, and update_pathfinding_cache().

Referenced by route(), and vertical_move_destination().

◆ get_radiation()

int map::get_radiation ( const tripoint p) const

Definition at line 4131 of file map.cpp.

4132{
4133 if( !inbounds( p ) ) {
4134 return 0;
4135 }
4136
4137 point l;
4138 submap *const current_submap = get_submap_at( p, l );
4139
4140 return current_submap->get_radiation( l );
4141}

References submap::get_radiation(), get_submap_at(), and inbounds().

Referenced by computer_session::action_geiger(), computer_session::action_irradiator(), check_art_charge_req(), relic_funcs::check_recharge_reqs(), editmap::draw_main_ui_overlay(), rad_scorch(), and Character::suffer_from_radiation().

◆ get_roof()

ter_id map::get_roof ( const tripoint p,
bool  allow_air 
) const
private

Definition at line 3200 of file map.cpp.

3201{
3202 // This function should not be called from the 2D mode
3203 // Just use t_dirt instead
3204 assert( zlevels );
3205
3206 if( p.z <= -OVERMAP_DEPTH ) {
3207 // Could be magma/"void" instead
3208 return t_rock_floor;
3209 }
3210
3211 const auto &ter_there = ter( p ).obj();
3212 const auto &roof = ter_there.roof;
3213 if( !roof ) {
3214 // No roof
3215 if( !allow_air ) {
3216 // TODO: Biomes? By setting? Forbid and treat as bug?
3217 if( p.z < 0 ) {
3218 return t_rock_floor_no_roof;
3219 }
3220
3221 return t_dirt;
3222 }
3223
3224 return t_open_air;
3225 }
3226
3227 ter_id new_ter = roof.id();
3228 if( new_ter == t_null ) {
3229 debugmsg( "map::get_new_floor: %d,%d,%d has invalid roof type %s",
3230 p.x, p.y, p.z, roof.c_str() );
3231 return t_dirt;
3232 }
3233
3234 if( p.z == -1 && new_ter == t_rock_floor ) {
3235 // HACK: A hack to work around not having a "solid earth" tile
3236 new_ter = t_dirt;
3237 }
3238
3239 return new_ter;
3240}
static const ter_str_id t_rock_floor_no_roof("t_rock_floor_no_roof")

References debugmsg, int_id< T >::id(), int_id< T >::obj(), OVERMAP_DEPTH, ter_t::roof, t_dirt, t_null, t_open_air, t_rock_floor, t_rock_floor_no_roof, ter(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by bash_ter_furn(), and bash_ter_success().

◆ get_signage()

std::string map::get_signage ( const tripoint p) const

Definition at line 4097 of file map.cpp.

4098{
4099 if( !inbounds( p ) ) {
4100 return "";
4101 }
4102
4103 point l;
4104 submap *const current_submap = get_submap_at( p, l );
4105
4106 return current_submap->get_signage( l );
4107}
std::string get_signage(point p) const
Definition: submap.cpp:161

References submap::get_signage(), get_submap_at(), and inbounds().

Referenced by game::extended_description(), game::place_player(), game::print_terrain_info(), and iexamine::sign().

◆ get_submap_at() [1/4]

◆ get_submap_at() [2/4]

submap * map::get_submap_at ( const tripoint p,
point offset_p 
) const
private

Get the submap pointer containing the specified position within the reality bubble.

The same as other get_submap_at, (p) must be valid (inbounds). Also writes the position within the submap to offset_p

Definition at line 8438 of file map.cpp.

8439{
8440 offset_p.x = p.x % SEEX;
8441 offset_p.y = p.y % SEEY;
8442 return get_submap_at( p );
8443}

References get_submap_at(), SEEX, SEEY, point::x, tripoint::x, point::y, and tripoint::y.

◆ get_submap_at() [3/4]

submap * map::get_submap_at ( point  p) const
inlineprivate

Definition at line 1814 of file map.h.

1814 {
1815 return get_submap_at( tripoint( p, abs_sub.z ) );
1816 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [4/4]

submap * map::get_submap_at ( point  p,
point offset_p 
) const
inlineprivate

Definition at line 1823 of file map.h.

1823 {
1824 return get_submap_at( { p, abs_sub.z }, offset_p );
1825 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at_grid() [1/2]

submap * map::get_submap_at_grid ( const tripoint gridp) const
private

Definition at line 8445 of file map.cpp.

8446{
8447 return getsubmap( get_nonant( gridp ) );
8448}

References get_nonant(), and getsubmap().

◆ get_submap_at_grid() [2/2]

◆ get_submaps_with_active_items()

const std::set< tripoint > & map::get_submaps_with_active_items ( ) const
inline

Definition at line 2015 of file map.h.

2015 {
2017 }

References submaps_with_active_items.

◆ get_temperature()

int map::get_temperature ( const tripoint p) const

Definition at line 4168 of file map.cpp.

4169{
4170 if( !inbounds( p ) ) {
4171 return 0;
4172 }
4173
4174 return get_submap_at( p )->get_temperature();
4175}
int get_temperature() const
Definition: submap.h:165

References get_submap_at(), submap::get_temperature(), and inbounds().

◆ get_ter_transforms_into()

ter_id map::get_ter_transforms_into ( const tripoint p) const

Definition at line 1671 of file map.cpp.

1672{
1673 return ter( p ).obj().transforms_into.id();
1674}
ter_str_id transforms_into
Definition: mapdata.h:470

References string_id< T >::id(), int_id< T >::obj(), ter(), and ter_t::transforms_into.

Referenced by iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), and iexamine::tree_hickory().

◆ get_vehicle_zones()

std::vector< zone_data * > map::get_vehicle_zones ( int  zlev)

Definition at line 998 of file map.cpp.

999{
1000 std::vector<zone_data *> veh_zones;
1001 bool rebuild = false;
1002 for( auto veh : get_cache( zlev ).zone_vehicles ) {
1003 if( veh->refresh_zones() ) {
1004 rebuild = true;
1005 }
1006 for( auto &zone : veh->loot_zones ) {
1007 veh_zones.emplace_back( &zone.second );
1008 }
1009 }
1010 if( rebuild ) {
1012 }
1013 return veh_zones;
1014}
static zone_manager & get_manager()
Definition: clzones.cpp:126
void cache_vzones()
Definition: clzones.cpp:624

References zone_manager::cache_vzones(), get_cache(), and zone_manager::get_manager().

Referenced by zone_manager::cache_vzones(), zone_manager::get_bottom_zone(), zone_manager::get_zone_at(), and zone_manager::get_zones().

◆ get_vehicles() [1/2]

◆ get_vehicles() [2/2]

VehicleList map::get_vehicles ( const tripoint start,
const tripoint end 
)

Definition at line 1039 of file map.cpp.

1040{
1041 const int chunk_sx = std::max( 0, ( start.x / SEEX ) - 1 );
1042 const int chunk_ex = std::min( my_MAPSIZE - 1, ( end.x / SEEX ) + 1 );
1043 const int chunk_sy = std::max( 0, ( start.y / SEEY ) - 1 );
1044 const int chunk_ey = std::min( my_MAPSIZE - 1, ( end.y / SEEY ) + 1 );
1045 const int chunk_sz = start.z;
1046 const int chunk_ez = end.z;
1047 VehicleList vehs;
1048
1049 for( int cx = chunk_sx; cx <= chunk_ex; ++cx ) {
1050 for( int cy = chunk_sy; cy <= chunk_ey; ++cy ) {
1051 for( int cz = chunk_sz; cz <= chunk_ez; ++cz ) {
1052 submap *current_submap = get_submap_at_grid( { cx, cy, cz } );
1053 for( const auto &elem : current_submap->vehicles ) {
1054 // Ensure the vehicle z-position is correct
1055 elem->sm_pos.z = cz;
1057 w.v = elem.get();
1058 w.pos = w.v->global_pos3();
1059 vehs.push_back( w );
1060 }
1061 }
1062 }
1063 }
1064
1065 return vehs;
1066}
tripoint pos
Definition: map.h:81
vehicle * v
Definition: map.h:82

References get_submap_at_grid(), vehicle::global_pos3(), my_MAPSIZE, wrapped_vehicle::pos, SEEX, SEEY, wrapped_vehicle::v, submap::vehicles, tripoint::x, tripoint::y, and tripoint::z.

◆ get_visibility()

visibility_type map::get_visibility ( lit_level  ll,
const visibility_variables cache 
) const

Definition at line 5760 of file map.cpp.

5762{
5763 switch( ll ) {
5764 case lit_level::DARK:
5765 // can't see this square at all
5766 if( cache.u_is_boomered ) {
5767 return VIS_BOOMER_DARK;
5768 } else {
5769 return VIS_DARK;
5770 }
5772 // can only tell that this square is bright
5773 if( cache.u_is_boomered ) {
5774 return VIS_BOOMER;
5775 } else {
5776 return VIS_LIT;
5777 }
5778
5779 case lit_level::LOW:
5780 // low light, square visible in monochrome
5781 case lit_level::LIT:
5782 // normal light
5783 case lit_level::BRIGHT:
5784 // bright light
5785 return VIS_CLEAR;
5786 case lit_level::BLANK:
5788 return VIS_HIDDEN;
5789 }
5790 return VIS_HIDDEN;
5791}
bool u_is_boomered
Definition: map.h:124

References BLANK, BRIGHT, BRIGHT_ONLY, DARK, LIT, LOW, MEMORIZED, visibility_variables::u_is_boomered, VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, and VIS_LIT.

Referenced by draw(), game::draw_look_around_cursor(), generate_weather_anim_frame(), get_known_connections(), and game::print_all_tile_info().

◆ get_visibility_variables_cache()

const visibility_variables & map::get_visibility_variables_cache ( ) const

Definition at line 5755 of file map.cpp.

5756{
5758}
visibility_variables visibility_variables_cache
Definition: map.h:1994

References visibility_variables_cache.

Referenced by draw(), generate_weather_anim_frame(), get_known_connections(), game::look_around(), live_view::show(), and editmap::update_view_with_help().

◆ get_wind_blockers()

std::tuple< maptile, maptile, maptile > map::get_wind_blockers ( const int &  winddirection,
const tripoint pos 
)

Definition at line 1893 of file map_field.cpp.

1895{
1896 static const std::array<std::pair<int, std::tuple< point, point, point >>, 9> outputs = {{
1897 { 330, std::make_tuple( point_east, point_north_east, point_south_east ) },
1898 { 301, std::make_tuple( point_south_east, point_east, point_south ) },
1899 { 240, std::make_tuple( point_south, point_south_west, point_south_east ) },
1900 { 211, std::make_tuple( point_south_west, point_west, point_south ) },
1901 { 150, std::make_tuple( point_west, point_north_west, point_south_west ) },
1902 { 121, std::make_tuple( point_north_west, point_north, point_west ) },
1903 { 60, std::make_tuple( point_north, point_north_west, point_north_east ) },
1904 { 31, std::make_tuple( point_north_east, point_east, point_north ) },
1905 { 0, std::make_tuple( point_east, point_north_east, point_south_east ) }
1906 }
1907 };
1908
1909 tripoint removepoint;
1910 tripoint removepoint2;
1911 tripoint removepoint3;
1912 for( const std::pair<int, std::tuple< point, point, point >> &val : outputs ) {
1913 if( winddirection >= val.first ) {
1914 removepoint = pos + std::get<0>( val.second );
1915 removepoint2 = pos + std::get<1>( val.second );
1916 removepoint3 = pos + std::get<2>( val.second );
1917 break;
1918 }
1919 }
1920
1921 const maptile remove_tile = maptile_at( removepoint );
1922 const maptile remove_tile2 = maptile_at( removepoint2 );
1923 const maptile remove_tile3 = maptile_at( removepoint3 );
1924 return std::make_tuple( remove_tile, remove_tile2, remove_tile3 );
1925}

References maptile_at(), point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, and point_west.

Referenced by spread_gas().

◆ getabs() [1/2]

tripoint map::getabs ( const tripoint p) const

Translates local (to this map) coordinates of a square to global absolute coordinates.

Coordinates is in the system that is used by the ter/furn/i_at functions. Output is in the same scale, but in global system.

Definition at line 8377 of file map.cpp.

8378{
8379 return sm_to_ms_copy( abs_sub.xy() ) + p;
8380}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by activity_on_turn_move_loot(), add_basecamp_storage_to_loot_zone_list(), add_item(), Character::add_known_trap(), jmapgen_zone::apply(), are_requirements_nearby(), game::autopilot_vehicles(), talk_function::basecamp_mission(), bash_ter_furn(), iexamine::bulletin_board(), butcher_corpse_activity(), can_do_activity_there(), iexamine::cardreader(), game::chat(), vehicle::autodrive_controller::check_drivable(), game::check_near_zone(), game::check_zone(), chop_plank_activity(), chop_tree_activity(), complete_construction(), construction_activity(), game::control_vehicle(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), npc::do_pulp(), construct::done_digormine_stair(), construct::done_mine_upstair(), draw_maptile(), editmap::edit_mapgen(), iexamine::elevator(), fill_funnels(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), find_valid_teleporters_omt(), activity_handlers::forage_finish(), inventory::form_from_map(), furn_set(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), generic_multi_activity_locations(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_known_connections(), zone_manager::get_point_set_loot(), getabs(), getglobal(), Character::global_square_location(), npc::go_to_omt_destination(), good_fishing_spot(), game::grabbed_furn_move(), grow_plant(), npc::guard_current_pos(), npc::handle_sound(), Character::knows_trap(), mine_activity(), npc::move(), perform_zone_activity_turn(), place_construction(), game::place_player(), basecamp::place_results(), game::place_vehicle_nearby(), iexamine::plant_seed(), game::pre_print_all_tile_info(), sounds::process_sounds(), plot_options::query_seed(), npc::reach_omt_destination(), remove_submap_turrets(), requirements_map(), zone_manager::rotate_zones(), conditional_t< T >::set_is_outside(), target_ui::set_last_target(), shoot(), iexamine::shrub_wildveggies(), smash(), spawn_monsters_submap_group(), debug_menu::spawn_nested_mapgen(), spread_gas(), ter_set(), tidy_activity(), vehicle::total_wind_epower_w(), translate_radius(), iexamine::trap(), update_suspension_cache(), use_charges_from_furn(), iexamine::use_furn_fake_item(), basecamp::validate_sort_points(), vehicle_activity(), vertical_move_destination(), iuse::weather_tool(), npc::worker_downtime(), and game::zones_manager().

◆ getabs() [2/2]

point map::getabs ( point  p) const
inline

Definition at line 1606 of file map.h.

1606 {
1607 return getabs( tripoint( p, abs_sub.z ) ).xy();
1608 }

References abs_sub, getabs(), tripoint::xy(), and tripoint::z.

◆ getglobal()

tripoint_abs_ms map::getglobal ( const tripoint p) const

Definition at line 8382 of file map.cpp.

8383{
8384 return tripoint_abs_ms( getabs( p ) );
8385}

References getabs().

Referenced by game::chat().

◆ getlocal() [1/3]

tripoint map::getlocal ( const tripoint p) const

Inverse of getabs.

Definition at line 8387 of file map.cpp.

8388{
8389 return p - sm_to_ms_copy( abs_sub.xy() );
8390}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by basecamp::abandon_camp(), activity_on_turn_move_loot(), zone_manager::add(), add_basecamp_storage_to_loot_zone_list(), grid_furn_transform_queue::apply(), talk_function::basecamp_mission(), activity_handlers::build_do_turn(), can_do_activity_there(), Character::check_outbounds_activity(), activity_handlers::chop_logs_finish(), activity_handlers::chop_planks_finish(), activity_handlers::chop_tree_do_turn(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), cleanup_tiles(), complete_construction(), veh_interact::complete_vehicle(), vehicle::autodrive_controller::compute_obstacles(), basecamp_action_components::consume_components(), deregister_vehicle_zone(), basecamp::distribute_food(), construct::done_digormine_stair(), construct::done_mine_upstair(), editmap::edit_mapgen(), npc::execute_action(), fetch_activity(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), activity_handlers::forage_finish(), basecamp::form_crafting_inventory(), inventory::form_from_zone(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), item::get_cable_target(), zone_manager::get_point_set_loot(), getlocal(), npc::go_to_omt_destination(), npc::good_escape_direction(), Character::has_destination_activity(), inbounds(), activity_handlers::jackhammer_do_turn(), activity_handlers::jackhammer_finish(), activity_handlers::milk_finish(), npc::move(), npc::move_to(), map_cursor::operator tripoint(), perform_zone_activity_turn(), activity_handlers::pickaxe_do_turn(), activity_handlers::pickaxe_finish(), teleporter_list::place_avatar_overmap(), basecamp::place_results(), game::place_vehicle_nearby(), activity_handlers::plant_seed_finish(), vehicle_part::properties_to_item(), activity_handlers::pulp_do_turn(), plot_options::query_seed(), npc::reach_omt_destination(), target_ui::recalc_aim_turning_penalty(), npc::regen_ai_cache(), requirements_map(), zone_manager::revert_vzones(), rotate(), zone_manager::rotate_zones(), activity_handlers::shear_finish(), debug_menu::spawn_nested_mapgen(), tidy_activity(), activity_handlers::travel_do_turn(), target_ui::try_reacquire_target(), update_suspension_cache(), basecamp::validate_sort_points(), veh_at(), activity_handlers::vehicle_finish(), vertical_move_destination(), npc::worker_downtime(), and game::zones_manager().

◆ getlocal() [2/3]

tripoint map::getlocal ( const tripoint_abs_ms p) const

Definition at line 8392 of file map.cpp.

8393{
8394 // TODO: fix point types
8395 return getlocal( p.raw() );
8396}
constexpr Point & raw()
Definition: coordinates.h:111

References getlocal(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ getlocal() [3/3]

point map::getlocal ( point  p) const
inline

Definition at line 1614 of file map.h.

1614 {
1615 return getlocal( tripoint( p, abs_sub.z ) ).xy();
1616 }

References abs_sub, getlocal(), tripoint::xy(), and tripoint::z.

◆ getmapsize()

int map::getmapsize ( ) const
inline

Definition at line 1632 of file map.h.

1632 {
1633 return my_MAPSIZE;
1634 }

References my_MAPSIZE.

Referenced by distribution_grid_tracker::load(), editmap::mapgen_preview(), and points_in_range().

◆ getsubmap()

submap * map::getsubmap ( size_t  grididx) const
private

Get the submap pointer with given index in grid, the index must be valid!

Definition at line 8408 of file map.cpp.

8409{
8410 if( grididx >= grid.size() ) {
8411 debugmsg( "Tried to access invalid grid index %d. Grid size: %d", grididx, grid.size() );
8412 return nullptr;
8413 }
8414 return grid[grididx];
8415}

References debugmsg, and grid.

Referenced by generate(), get_submap_at_grid(), and saven().

◆ graffiti_at()

const std::string & map::graffiti_at ( const tripoint p) const

Definition at line 7939 of file map.cpp.

7940{
7941 if( !inbounds( p ) ) {
7942 static const std::string empty_string;
7943 return empty_string;
7944 }
7945 point l;
7946 submap *const current_submap = get_submap_at( p, l );
7947 return current_submap->get_graffiti( l );
7948}
const std::string & get_graffiti(point p) const
Definition: submap.cpp:123

References submap::get_graffiti(), get_submap_at(), and inbounds().

Referenced by advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ grow_plant()

void map::grow_plant ( const tripoint p)
protected

Try to grow a harvestable plant to the next stage(s).

Definition at line 7262 of file map.cpp.

7263{
7264 const auto &furn = this->furn( p ).obj();
7265 if( !furn.has_flag( "PLANT" ) ) {
7266 return;
7267 }
7268 // Can't use item_stack::only_item() since there might be fertilizer
7269 map_stack items = i_at( p );
7270 map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
7271 return it.is_seed();
7272 } );
7273
7274 if( seed == items.end() ) {
7275 // No seed there anymore, we don't know what kind of plant it was.
7276 // TODO: Fix point types
7277 const oter_id ot = overmap_buffer.ter( project_to<coords::omt>( tripoint_abs_ms( getabs( p ) ) ) );
7278 dbg( DL::Error ) << "a planted item at " << p
7279 << " (within overmap terrain " << ot.id().str() << ") has no seed data";
7280 i_clear( p );
7281 furn_set( p, f_null );
7282 return;
7283 }
7284 const time_duration plantEpoch = seed->get_plant_epoch();
7285 if( seed->age() >= plantEpoch * furn.plant->growth_multiplier &&
7286 !furn.has_flag( "GROWTH_HARVEST" ) ) {
7287 if( seed->age() < plantEpoch * 2 ) {
7288 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7289 return;
7290 }
7291
7292 // Remove fertilizer if any
7293 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7294 return it.has_flag( "FERTILIZER" );
7295 } );
7296 if( fertilizer != items.end() ) {
7297 items.erase( fertilizer );
7298 }
7299
7300 rotten_item_spawn( *seed, p );
7301 furn_set( p, furn_str_id( furn.plant->transform ) );
7302 } else if( seed->age() < plantEpoch * 3 * furn.plant->growth_multiplier ) {
7303 if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7304 return;
7305 }
7306
7307 // Remove fertilizer if any
7308 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7309 return it.has_flag( "FERTILIZER" );
7310 } );
7311 if( fertilizer != items.end() ) {
7312 items.erase( fertilizer );
7313 }
7314
7315 rotten_item_spawn( *seed, p );
7316 //You've skipped the seedling stage so roll monsters twice
7317 if( !has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7318 rotten_item_spawn( *seed, p );
7319 }
7320 furn_set( p, furn_str_id( furn.plant->transform ) );
7321 } else {
7322 //You've skipped two stages so roll monsters two times
7323 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7324 rotten_item_spawn( *seed, p );
7325 rotten_item_spawn( *seed, p );
7326 //One stage change
7327 } else if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7328 rotten_item_spawn( *seed, p );
7329 //Goes from seed to harvest in one check
7330 } else {
7331 rotten_item_spawn( *seed, p );
7332 rotten_item_spawn( *seed, p );
7333 rotten_item_spawn( *seed, p );
7334 }
7335 furn_set( p, furn_str_id( furn.plant->transform ) );
7336 }
7337 }
7338}
iterator erase(const_iterator it) override
Definition: map.cpp:153
void rotten_item_spawn(const item &item, const tripoint &p)
Checks to see if the item that is rotting away generates a creature when it does.
Definition: map.cpp:7214
string_id< furn_t > furn_str_id
Definition: type_id.h:65

References item_stack::begin(), dbg, item_stack::end(), map_stack::erase(), Error, f_null, furn(), furn_set(), getabs(), has_flag_furn(), i_at(), i_clear(), int_id< T >::id(), int_id< T >::obj(), overmap_buffer, rotten_item_spawn(), iuse::seed(), string_id< T >::str(), and overmapbuffer::ter().

Referenced by actualize().

◆ has_adjacent_furniture_with()

bool map::has_adjacent_furniture_with ( const tripoint p,
const std::function< bool(const furn_t &)> &  filter 
)

Returns true if there is furniture for which filter returns true in a 1 tile radius of p.

Pass return_true<furn_t> to detect all adjacent furniture.

Parameters
pthe location to check at
filterwhat to filter the furniture by.

Definition at line 2802 of file map.cpp.

2804{
2805 for( const tripoint &adj : points_in_radius( p, 1 ) ) {
2806 if( has_furn( adj ) && filter( furn( adj ).obj() ) ) {
2807 return true;
2808 }
2809 }
2810
2811 return false;
2812}

References furn(), has_furn(), and points_in_radius().

◆ has_flag() [1/4]

bool map::has_flag ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2374 of file map.cpp.

2375{
2376 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2377}

References has_flag_ter_or_furn().

Referenced by accessible_items(), Character::activate_bionic(), add_item(), add_item_or_charges(), npc::assess_danger(), bash(), bash_ter_furn(), bash_ter_success(), start_location::burn(), activity_handlers::burrow_finish(), game::butcher(), can_do_activity_there(), can_examine_at(), can_move_vertical_at(), can_put_items_ter_furn(), monster::can_reach_to(), iexamine::chainfence(), construct::check_empty(), vehicle::check_falling_or_floating(), construct::check_support(), chop_tree_activity(), climb_difficulty(), close_door(), doors::close_door(), collapse_at(), collapse_check(), consider_butchery(), iexamine::curtains(), displace_water(), character_funcs::do_pause(), dont_draw_lower_floor(), iexamine::door_peephole(), draw_lab(), drop_everything(), drop_or_embed_projectile(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_shutdown(), features(), find_closest_stair(), find_furnitures_or_vparts_with_flag_in_radius(), game::find_or_make_stairs(), flammable_items_at(), game::fling_creature(), game::forced_door_closing(), generic_multi_activity_do(), game::get_dangerous_tile(), get_fire_fuel_string(), game::get_fishable_locations(), overmap_ui::get_overmap_path_to(), game::grabbed_furn_move(), has_flag(), has_nearby_chair(), has_nearby_table(), haul(), hit_with_fire(), in_spell_aoe(), vehicle::interact_with(), is_divable(), game::is_empty(), is_flammable(), is_water_shallow_current(), game::knockback(), mine_activity(), mop_spills(), monster::move(), avatar_action::move(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_minefield(), item::on_drop(), open(), open_door(), vehicle::part_collision(), activity_handlers::pickaxe_finish(), game::place_player(), game::print_fields_info(), game::print_items_info(), item::process_extinguish(), process_fields_in_submap(), item::process_litcig(), spell_effect::projectile_attack(), propagate_field(), propagate_suspension_check(), avatar_action::ramp_move(), rate_location(), route(), area_expander::run(), Character::run_cost(), conditional_t< T >::set_is_outside(), vehicle::shift_zlevel(), shoot(), spawn_an_item(), spawn_items(), spell_effect::spell_effect_cone(), fungal_effects::spread_fungus(), fungal_effects::spread_fungus_one_tile(), monster::stumble(), Character::suffer_from_other_mutations(), avatar_action::swim(), test_passable(), game::update_stair_monsters(), editmap::update_view_with_help(), place_trap_actor::use(), deploy_tent_actor::use(), use_charges_from_furn(), game::use_computer(), game::vertical_move(), vertical_move_destination(), game::walk_move(), water_from(), and npc::worker_downtime().

◆ has_flag() [2/4]

bool map::has_flag ( const std::string &  flag,
point  p 
) const
inline

Definition at line 904 of file map.h.

904 {
905 return has_flag( flag, tripoint( p, abs_sub.z ) );
906 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [3/4]

bool map::has_flag ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2417 of file map.cpp.

2418{
2419 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2420}

References has_flag_ter_or_furn().

◆ has_flag() [4/4]

bool map::has_flag ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 939 of file map.h.

939 {
940 return has_flag( flag, tripoint( p, abs_sub.z ) );
941 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag_furn() [1/4]

◆ has_flag_furn() [2/4]

bool map::has_flag_furn ( const std::string &  flag,
point  p 
) const
inline

Definition at line 924 of file map.h.

924 {
925 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
926 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [3/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2427 of file map.cpp.

2428{
2429 return furn( p ).obj().has_flag( flag );
2430}

References furn(), map_data_common_t::has_flag(), and int_id< T >::obj().

◆ has_flag_furn() [4/4]

bool map::has_flag_furn ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 949 of file map.h.

949 {
950 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
951 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn_or_vpart()

bool map::has_flag_furn_or_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2438 of file map.cpp.

2439{
2440 return has_flag_furn( flag, p ) || has_flag_vpart( flag, p );
2441}
bool has_flag_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2432

References has_flag_furn(), and has_flag_vpart().

Referenced by find_furnitures_or_vparts_with_flag_in_radius(), activity_handlers::operation_do_turn(), and operator_present().

◆ has_flag_ter() [1/4]

◆ has_flag_ter() [2/4]

bool map::has_flag_ter ( const std::string &  flag,
point  p 
) const
inline

Definition at line 919 of file map.h.

919 {
920 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
921 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [3/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2422 of file map.cpp.

2423{
2424 return ter( p ).obj().has_flag( flag );
2425}

References map_data_common_t::has_flag(), int_id< T >::obj(), and ter().

◆ has_flag_ter() [4/4]

bool map::has_flag_ter ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 944 of file map.h.

944 {
945 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
946 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter_or_furn() [1/4]

◆ has_flag_ter_or_furn() [2/4]

bool map::has_flag_ter_or_furn ( const std::string &  flag,
point  p 
) const
inline

Definition at line 933 of file map.h.

933 {
934 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
935 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [3/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2443 of file map.cpp.

2444{
2445 if( !inbounds( p ) ) {
2446 return false;
2447 }
2448
2449 point l;
2450 submap *const current_submap = get_submap_at( p, l );
2451
2452 return current_submap && //FIXME: can be null during mapgen
2453 ( current_submap->get_ter( l ).obj().has_flag( flag ) ||
2454 current_submap->get_furn( l ).obj().has_flag( flag ) );
2455}

References submap::get_furn(), get_submap_at(), submap::get_ter(), map_data_common_t::has_flag(), inbounds(), and int_id< T >::obj().

◆ has_flag_ter_or_furn() [4/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 954 of file map.h.

954 {
955 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
956 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_vpart()

bool map::has_flag_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2432 of file map.cpp.

2433{
2434 const optional_vpart_position vp = veh_at( p );
2435 return static_cast<bool>( vp.part_with_feature( flag, true ) );
2436}

References optional_vpart_position::part_with_feature(), and veh_at().

Referenced by has_flag_furn_or_vpart().

◆ has_floor()

bool map::has_floor ( const tripoint p) const

◆ has_floor_or_support()

bool map::has_floor_or_support ( const tripoint p) const

Definition at line 2120 of file map.cpp.

2121{
2122 const tripoint below( p.xy(), p.z - 1 );
2123 return !valid_move( p, below, false, true );
2124}

References valid_move(), tripoint::xy(), and tripoint::z.

Referenced by monster::move(), game::print_terrain_info(), avatar_action::ramp_move(), reachable_flood_steps(), smash(), and game::vertical_move().

◆ has_furn() [1/2]

◆ has_furn() [2/2]

bool map::has_furn ( point  p) const
inline

Definition at line 789 of file map.h.

789 {
790 return has_furn( tripoint( p, abs_sub.z ) );
791 }

References abs_sub, has_furn(), and tripoint::z.

◆ has_graffiti_at()

bool map::has_graffiti_at ( const tripoint p) const

Definition at line 7950 of file map.cpp.

7951{
7952 if( !inbounds( p ) ) {
7953 return false;
7954 }
7955 point l;
7956 submap *const current_submap = get_submap_at( p, l );
7957 return current_submap->has_graffiti( l );
7958}
bool has_graffiti(point p) const
Definition: submap.cpp:118

References get_submap_at(), submap::has_graffiti(), and inbounds().

Referenced by editmap::draw_main_ui_overlay(), advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ has_items()

bool map::has_items ( const tripoint p) const

Checks for existence of items.

Faster than i_at(p).empty

Definition at line 4868 of file map.cpp.

4869{
4870 if( !inbounds( p ) ) {
4871 return false;
4872 }
4873
4874 point l;
4875 submap *const current_submap = get_submap_at( p, l );
4876
4877 return !current_submap->get_items( l ).empty();
4878}

References submap::get_items(), get_submap_at(), and inbounds().

Referenced by Character::activate_bionic(), bash_items(), can_do_activity_there(), can_examine_at(), can_pickup_at(), drop_furniture(), drop_items(), flammable_items_at(), inventory::form_from_map(), generate_lightmap(), has_clear_path_to_pickup_items(), haul(), iuse::note_bionics(), npc::pick_up_item(), game::place_player(), sees_some_items(), and smash_items().

◆ has_nearby_chair()

bool map::has_nearby_chair ( const tripoint p,
int  radius = 1 
)

Check whether a chair or vehicle seat is nearby.

Definition at line 2841 of file map.cpp.

2842{
2843 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2844 const optional_vpart_position vp = veh_at( pt );
2845 if( has_flag( "CAN_SIT", pt ) ) {
2846 return true;
2847 }
2848 if( vp && vp->vehicle().has_part( "SEAT" ) ) {
2849 return true;
2850 }
2851 }
2852 return false;
2853}

References has_flag(), points_in_radius(), and veh_at().

◆ has_nearby_fire()

bool map::has_nearby_fire ( const tripoint p,
int  radius = 1 
)

Definition at line 2814 of file map.cpp.

2815{
2816 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2817 if( get_field( pt, fd_fire ) != nullptr ) {
2818 return true;
2819 }
2820 if( has_flag_ter_or_furn( "USABLE_FIRE", pt ) ) {
2821 return true;
2822 }
2823 }
2824 return false;
2825}

References fd_fire, get_field(), has_flag_ter_or_furn(), and points_in_radius().

Referenced by iexamine::fireplace(), and inventory::form_from_map().

◆ has_nearby_table()

bool map::has_nearby_table ( const tripoint p,
int  radius = 1 
)

Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating.

Definition at line 2827 of file map.cpp.

2828{
2829 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2830 const optional_vpart_position vp = veh_at( p );
2831 if( has_flag( "FLAT_SURF", pt ) ) {
2832 return true;
2833 }
2834 if( vp && ( vp->vehicle().has_part( "KITCHEN" ) || vp->vehicle().has_part( "FLAT_SURF" ) ) ) {
2835 return true;
2836 }
2837 }
2838 return false;
2839}

References has_flag(), points_in_radius(), and veh_at().

Referenced by can_do_activity_there(), and consider_butchery().

◆ has_zlevels()

◆ hit_with_acid()

bool map::hit_with_acid ( const tripoint p)

Definition at line 3926 of file map.cpp.

3927{
3928 if( passable( p ) ) {
3929 return false; // Didn't hit the tile!
3930 }
3931 const ter_id t = ter( p );
3932 if( t == t_wall_glass || t == t_wall_glass_alarm ||
3933 t == t_vat ) {
3934 ter_set( p, t_floor );
3935 } else if( t == t_door_c || t == t_door_locked || t == t_door_locked_peep ||
3936 t == t_door_locked_alarm ) {
3937 if( one_in( 3 ) ) {
3938 ter_set( p, t_door_b );
3939 }
3940 } else if( t == t_door_bar_c || t == t_door_bar_o || t == t_door_bar_locked || t == t_bars ||
3941 t == t_reb_cage ) {
3942 ter_set( p, t_floor );
3943 add_msg( m_warning, _( "The metal bars melt!" ) );
3944 } else if( t == t_door_b ) {
3945 if( one_in( 4 ) ) {
3946 ter_set( p, t_door_frame );
3947 } else {
3948 return false;
3949 }
3950 } else if( t == t_window || t == t_window_alarm || t == t_window_no_curtains ) {
3951 ter_set( p, t_window_empty );
3952 } else if( t == t_wax ) {
3953 ter_set( p, t_floor_wax );
3954 } else if( t == t_gas_pump || t == t_gas_pump_smashed ) {
3955 return false;
3956 } else if( t == t_card_science || t == t_card_military || t == t_card_industrial ) {
3958 }
3959 return true;
3960}
@ m_warning
Definition: enums.h:264
ter_id t_card_industrial
Definition: mapdata.cpp:724
ter_id t_floor_wax
Definition: mapdata.cpp:687
ter_id t_reb_cage
Definition: mapdata.cpp:656
ter_id t_card_military
Definition: mapdata.cpp:724
ter_id t_door_bar_locked
Definition: mapdata.cpp:665
ter_id t_window_alarm
Definition: mapdata.cpp:670
ter_id t_door_bar_o
Definition: mapdata.cpp:665
ter_id t_gas_pump
Definition: mapdata.cpp:700
ter_id t_wall_glass_alarm
Definition: mapdata.cpp:651
ter_id t_card_reader_broken
Definition: mapdata.cpp:724
ter_id t_gas_pump_smashed
Definition: mapdata.cpp:700
ter_id t_door_locked_peep
Definition: mapdata.cpp:659
ter_id t_door_bar_c
Definition: mapdata.cpp:665
ter_id t_door_frame
Definition: mapdata.cpp:660
ter_id t_vat
Definition: mapdata.cpp:712
ter_id t_window_no_curtains
Definition: mapdata.cpp:674
ter_id t_wax
Definition: mapdata.cpp:687
ter_id t_window_empty
Definition: mapdata.cpp:670
ter_id t_door_b
Definition: mapdata.cpp:658

References _, add_msg(), m_warning, one_in(), passable(), t_bars, t_card_industrial, t_card_military, t_card_reader_broken, t_card_science, t_door_b, t_door_bar_c, t_door_bar_locked, t_door_bar_o, t_door_c, t_door_frame, t_door_locked, t_door_locked_alarm, t_door_locked_peep, t_floor, t_floor_wax, t_gas_pump, t_gas_pump_smashed, t_reb_cage, t_vat, t_wall_glass, t_wall_glass_alarm, t_wax, t_window, t_window_alarm, t_window_empty, t_window_no_curtains, ter(), and ter_set().

◆ hit_with_fire()

bool map::hit_with_fire ( const tripoint p)

Definition at line 3963 of file map.cpp.

3964{
3965 if( passable( p ) ) {
3966 return false; // Didn't hit the tile!
3967 }
3968
3969 // non passable but flammable terrain, set it on fire
3970 if( has_flag( "FLAMMABLE", p ) || has_flag( "FLAMMABLE_ASH", p ) ) {
3971 add_field( p, fd_fire, 3 );
3972 }
3973 return true;
3974}

References add_field(), fd_fire, has_flag(), and passable().

Referenced by mattack::flame().

◆ hoist_submap_camp()

basecamp map::hoist_submap_camp ( const tripoint p)

Definition at line 5683 of file map.cpp.

5684{
5685 basecamp *pcamp = get_submap_at( p )->camp.get();
5686 return pcamp ? *pcamp : basecamp();
5687}
std::unique_ptr< basecamp > camp
Definition: submap.h:220

References submap::camp, and get_submap_at().

Referenced by game::validate_camps().

◆ i_at() [1/2]

map_stack map::i_at ( const tripoint p)

Definition at line 4187 of file map.cpp.

4188{
4189 if( !inbounds( p ) ) {
4190 nulitems.clear();
4191 return map_stack{ &nulitems, p, this };
4192 }
4193
4194 point l;
4195 submap *const current_submap = get_submap_at( p, l );
4196
4197 return map_stack{ &current_submap->get_items( l ), p, this };
4198}
static cata::colony< item > nulitems
Definition: map.cpp:141

References submap::get_items(), get_submap_at(), inbounds(), and nulitems.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_irradiator(), computer_session::action_list_bionics(), computer_session::action_sample(), Character::activate_bionic(), activity_on_turn_move_loot(), add_item_or_charges(), advanced_inventory_pane::add_items_from_area(), iexamine::aggie_plant(), apply_camp_ownership(), apply_faction_ownership(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), are_requirements_nearby(), iexamine::autoclave_full(), character_funcs::base_comfort_value(), bash_furn_success(), bash_items(), explosion_handler::ExplosionProcess::blast_tile(), board_up(), MapExtras::burned_ground_parser(), game::butcher(), butcher_corpse_activity(), can_butcher_at(), can_do_activity_there(), iexamine::can_fertilize(), advanced_inventory::change_square(), construct::check_empty(), chop_plank_activity(), doors::close_door(), complete_construction(), iuse::directional_antenna(), iexamine::dirtmound(), displace_items_except_one_liquid(), basecamp::distribute_food(), construct::done_grave(), drop_furniture(), drop_items(), editmap::edit_itm(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), fetch_activity(), talk_function::field_harvest(), fill_funnels(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), flammable_items_at(), Character::floor_item_warmth(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), free_volume(), fromPumpFuel(), furnname(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::gaspump(), generate_lightmap(), generic_multi_activity_locations(), advanced_inv_area::get_container(), player::get_eligible_containers_for_crafting(), advanced_inv_area::get_item_count(), iexamine::getNearFilledGasTank(), game::grabbed_furn_move(), grow_plant(), liquid_handler::handle_liquid_from_ground(), iexamine::harvest_plant(), i_at(), i_rem(), Character::is_snuggling(), activity_handlers::jackhammer_finish(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), advanced_inventory_pane::load_settings(), activity_handlers::longsalvage_finish(), talk_function::loot_building(), max_volume(), mill_activate(), iexamine::mill_finalize(), mop_spills(), advanced_inventory::move_all_items(), explosion_handler::ExplosionProcess::move_entity(), MapExtras::mx_supplydrop(), iuse::note_bionics(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), npc::pick_up_item_map(), activity_handlers::pickaxe_finish(), game::place_player(), iexamine::pour_into_keg(), firestarter_actor::prep_firestarter_use(), game::print_items_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pulp_do_turn(), iexamine::quern_examine(), plot_options::query_seed(), iexamine::recycle_compactor(), iexamine::reload_furniture(), requirements_map(), rod_fish(), explosion_handler::ExplosionProcess::run(), npc::see_item_say_smth(), serialize_liquid_source(), iexamine::shrub_wildveggies(), smash(), smash_items(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), spell_move(), fungal_effects::spread_fungus_one_tile(), game::start_hauling(), basecamp::start_relay_hide_site(), stored_volume(), tidy_activity(), tinder_at(), iexamine::toilet(), iexamine::toPumpFuel(), iexamine::tree_maple_tapped(), try_fuel_fire(), editmap::update_view_with_help(), enzlave_actor::use(), use_amount_square(), use_charges(), use_charges_from_furn(), iexamine::use_furn_fake_item(), and iexamine::vending().

◆ i_at() [2/2]

map_stack map::i_at ( point  p)
inline

Definition at line 1182 of file map.h.

1182 {
1183 return i_at( tripoint( p, abs_sub.z ) );
1184 }

References abs_sub, i_at(), and tripoint::z.

◆ i_clear() [1/2]

void map::i_clear ( const tripoint p)

Definition at line 4225 of file map.cpp.

4226{
4227 point l;
4228 submap *const current_submap = get_submap_at( p, l );
4229
4230 for( item &it : current_submap->get_items( l ) ) {
4231 // remove from the active items cache (if it isn't there does nothing)
4232 current_submap->active_items.remove( &it );
4233 }
4234 if( current_submap->active_items.empty() ) {
4235 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4236 }
4237
4238 current_submap->set_lum( l, 0 );
4239 current_submap->get_items( l ).clear();
4240}
void remove(const item *it)
Removes the item if it is in the cache.
void set_lum(point p, uint8_t luminance)
Definition: submap.h:125

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submap::set_lum(), submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_conveyor(), iexamine::aggie_plant(), jmapgen_terrain::apply(), iexamine::arcfurnace_empty(), explosion_handler::ExplosionProcess::blast_tile(), board_up(), doors::close_door(), MapExtras::dead_vegetation_parser(), basecamp::distribute_food(), draw_lab(), drop_furniture(), drop_items(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), iexamine::harvest_plant(), i_clear(), iexamine::keg(), iexamine::kiln_empty(), mapgen_lake_shore(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), rad_scorch(), explosion_handler::ExplosionProcess::run(), and iexamine::tree_maple_tapped().

◆ i_clear() [2/2]

void map::i_clear ( point  p)
inline

Definition at line 1187 of file map.h.

1187 {
1188 i_clear( tripoint( p, abs_sub.z ) );
1189 }

References abs_sub, i_clear(), and tripoint::z.

◆ i_rem() [1/4]

void map::i_rem ( const tripoint p,
item it 
)

Definition at line 4216 of file map.cpp.

4217{
4218 map_stack map_items = i_at( p );
4220 if( iter != map_items.end() ) {
4221 i_rem( p, iter );
4222 }
4223}
iterator get_iterator_from_pointer(item *it)
Definition: item_stack.cpp:68
map_stack::iterator i_rem(const tripoint &p, map_stack::const_iterator it)
Definition: map.cpp:4200

References item_stack::end(), item_stack::get_iterator_from_pointer(), i_at(), and i_rem().

◆ i_rem() [2/4]

map_stack::iterator map::i_rem ( const tripoint p,
map_stack::const_iterator  it 
)

Definition at line 4200 of file map.cpp.

4201{
4202 point l;
4203 submap *const current_submap = get_submap_at( p, l );
4204
4205 // remove from the active items cache (if it isn't there does nothing)
4206 current_submap->active_items.remove( &*it );
4207 if( current_submap->active_items.empty() ) {
4208 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4209 }
4210
4211 current_submap->update_lum_rem( l, *it );
4212
4213 return current_submap->get_items( l ).erase( it );
4214}
void update_lum_rem(point p, const item &i)
Definition: submap.cpp:56

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submaps_with_active_items, submap::update_lum_rem(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), chop_plank_activity(), delete_cyborg_item(), iexamine::elevator(), map_stack::erase(), iexamine::fvat_full(), i_rem(), mill_activate(), explosion_handler::ExplosionProcess::move_entity(), move_item(), om_set_hide_site(), rcdrive(), remove_rotten_items(), smash_items(), and smoker_activate().

◆ i_rem() [3/4]

map_stack::iterator map::i_rem ( point  location,
map_stack::const_iterator  it 
)
inline

Definition at line 1193 of file map.h.

1193 {
1194 return i_rem( tripoint( location, abs_sub.z ), it );
1195 }

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [4/4]

void map::i_rem ( point  p,
item it 
)
inline

Definition at line 1197 of file map.h.

1197 {
1198 i_rem( tripoint( p, abs_sub.z ), it );
1199 }

References abs_sub, i_rem(), and tripoint::z.

◆ impassable() [1/2]

◆ impassable() [2/2]

bool map::impassable ( point  p) const
inline

Definition at line 566 of file map.h.

566 {
567 return !passable( p );
568 }

References passable().

◆ impassable_ter_furn()

bool map::impassable_ter_furn ( const tripoint p) const

Definition at line 1892 of file map.cpp.

1893{
1894 return !passable_ter_furn( p );
1895}
bool passable_ter_furn(const tripoint &p) const
Definition: map.cpp:1897

References passable_ter_furn().

Referenced by vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), displace_water(), and vehicle::part_collision().

◆ inbounds() [1/3]

bool map::inbounds ( const tripoint p) const
virtual

Reimplemented in tinymap.

Definition at line 7873 of file map.cpp.

7874{
7875 static constexpr tripoint map_boundary_min( 0, 0, -OVERMAP_DEPTH );
7876 static constexpr tripoint map_boundary_max( MAPSIZE_Y, MAPSIZE_X, OVERMAP_HEIGHT + 1 );
7877
7878 static constexpr half_open_cuboid<tripoint> map_boundaries(
7879 map_boundary_min, map_boundary_max );
7880
7881 return map_boundaries.contains( p );
7882}

References half_open_cuboid< Tripoint, >::contains(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by vehicle::act_on_map(), activity_on_turn_move_loot(), add_field(), add_item(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), add_vehicle(), add_vehicle_to_cache(), adjust_radiation(), ambient_light_at(), grid_furn_transform_queue::apply(), apply_light_source(), apply_vision_transparency_cache(), bash(), bash_rating(), build_sunlight_cache(), Character::check_outbounds_activity(), clear_path(), clear_vehicle_cache(), clear_vehicle_point_from_cache(), computer_at(), vehicle::damage_direct(), delete_graffiti(), delete_signage(), displace_vehicle(), do_vehicle_caching(), draw(), game::draw_look_around_cursor(), drawsq(), ranged::execute_shaped_attack(), field_at(), explosion_handler::ExplosionProcess::fill_maps(), furn(), furn_set(), generate_lightmap(), generic_multi_activity_handler(), get_field(), get_known_connections(), get_radiation(), get_signage(), get_submap_at(), get_temperature(), graffiti_at(), has_flag_ter_or_furn(), has_floor(), has_graffiti_at(), has_items(), i_at(), inbounds(), is_bashable(), is_outside(), explosion_handler::legacy_blast(), light_at(), game::load_npcs(), maptile_at(), map_stack::max_volume(), move_cost(), move_cost_ter_furn(), explosion_handler::ExplosionProcess::move_entity(), obscured_by_vehicle_rotation(), obstructed_by_vehicle_rotation(), activity_handlers::operation_do_turn(), partial_con_at(), partial_con_remove(), partial_con_set(), pl_line_of_sight(), pl_sees(), game::print_all_tile_info(), remove_field(), remove_trap(), restore_vision_transparency_cache(), route(), npc::saw_player_recently(), sees(), set_graffiti(), set_radiation(), set_seen_cache_dirty(), set_signage(), set_temperature(), set_transparency_cache_dirty(), game::shift_monsters(), shift_traps(), shoot(), spawn_items(), ter(), ter_set(), tr_at(), trap_set(), update_suspension_cache(), valid_move(), and veh_at().

◆ inbounds() [2/3]

bool map::inbounds ( const tripoint_abs_ms p) const

Definition at line 7868 of file map.cpp.

7869{
7870 return inbounds( getlocal( p ) );
7871}

References getlocal(), and inbounds().

◆ inbounds() [3/3]

bool map::inbounds ( point  p) const
inline

Definition at line 1619 of file map.h.

1619 {
1620 return inbounds( tripoint( p, 0 ) );
1621 }

References inbounds().

◆ inbounds_z()

◆ invalidate_map_cache()

◆ invalidate_max_populated_zlev()

void map::invalidate_max_populated_zlev ( int  zlev)
private

Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value.

Parameters
zlevzlevel where uniformity change occured

Definition at line 9146 of file map.cpp.

9147{
9148 if( max_populated_zlev && max_populated_zlev->second < zlev ) {
9149 max_populated_zlev->second = zlev;
9150 }
9151}

References max_populated_zlev.

Referenced by add_field(), add_item(), add_vehicle(), displace_vehicle(), furn_set(), shift_vehicle_z(), and ter_set().

◆ is_bashable() [1/2]

bool map::is_bashable ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.

Definition at line 2506 of file map.cpp.

2507{
2508 if( !inbounds( p ) ) {
2509 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2510 return false;
2511 }
2512
2513 if( veh_at( p ).obstacle_at_part() ) {
2514 return true;
2515 }
2516
2517 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2518 return true;
2519 }
2520
2521 const auto &ter_bash = ter( p ).obj().bash;
2522 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2523}

References bash(), map_data_common_t::bash, dbg, furn(), has_furn(), inbounds(), int_id< T >::obj(), map_bash_info::str_max, ter(), veh_at(), and Warn.

Referenced by MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), features(), game::fling_creature(), is_bashable(), npc::move_to(), MapExtras::mx_helicopter(), and activity_handlers::pickaxe_finish().

◆ is_bashable() [2/2]

bool map::is_bashable ( point  p) const
inline

Definition at line 961 of file map.h.

961 {
962 return is_bashable( tripoint( p, abs_sub.z ) );
963 }

References abs_sub, is_bashable(), and tripoint::z.

◆ is_bashable_furn() [1/2]

bool map::is_bashable_furn ( const tripoint p) const

Returns true if the furniture at p is bashable.

Definition at line 2531 of file map.cpp.

2532{
2533 return has_furn( p ) && furn( p ).obj().bash.str_max != -1;
2534}

References map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), and map_bash_info::str_max.

Referenced by is_bashable_furn(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_furn() [2/2]

bool map::is_bashable_furn ( point  p) const
inline

Definition at line 971 of file map.h.

971 {
972 return is_bashable_furn( tripoint( p, abs_sub.z ) );
973 }
bool is_bashable_furn(const tripoint &p) const
Returns true if the furniture at p is bashable.
Definition: map.cpp:2531

References abs_sub, is_bashable_furn(), and tripoint::z.

◆ is_bashable_ter() [1/2]

bool map::is_bashable_ter ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the terrain at p is bashable.

Definition at line 2525 of file map.cpp.

2526{
2527 const auto &ter_bash = ter( p ).obj().bash;
2528 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2529}

References map_data_common_t::bash, int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by is_bashable_ter(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter() [2/2]

bool map::is_bashable_ter ( point  p) const
inline

Definition at line 966 of file map.h.

966 {
967 return is_bashable_ter( tripoint( p, abs_sub.z ) );
968 }
bool is_bashable_ter(const tripoint &p, bool allow_floor=false) const
Returns true if the terrain at p is bashable.
Definition: map.cpp:2525

References abs_sub, is_bashable_ter(), and tripoint::z.

◆ is_bashable_ter_furn() [1/2]

bool map::is_bashable_ter_furn ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the furniture or terrain at p is bashable.

Definition at line 2536 of file map.cpp.

2537{
2538 return is_bashable_furn( p ) || is_bashable_ter( p, allow_floor );
2539}

References is_bashable_furn(), and is_bashable_ter().

Referenced by is_bashable_ter_furn(), and vehicle::part_collision().

◆ is_bashable_ter_furn() [2/2]

bool map::is_bashable_ter_furn ( point  p) const
inline

Definition at line 976 of file map.h.

976 {
977 return is_bashable_ter_furn( tripoint( p, abs_sub.z ) );
978 }
bool is_bashable_ter_furn(const tripoint &p, bool allow_floor=false) const
Returns true if the furniture or terrain at p is bashable.
Definition: map.cpp:2536

References abs_sub, is_bashable_ter_furn(), and tripoint::z.

◆ is_cornerfloor()

bool map::is_cornerfloor ( const tripoint p) const

Definition at line 9083 of file map.cpp.

9084{
9085 if( impassable( p ) ) {
9086 return false;
9087 }
9088 std::set<tripoint> impassable_adjacent;
9089 for( const tripoint &pt : points_in_radius( p, 1 ) ) {
9090 if( impassable( pt ) ) {
9091 impassable_adjacent.insert( pt );
9092 }
9093 }
9094 if( !impassable_adjacent.empty() ) {
9095 //to check if a floor is a corner we first search if any of its diagonal adjacent points is impassable
9096 std::set< tripoint> diagonals = { p + tripoint_north_east, p + tripoint_north_west, p + tripoint_south_east, p + tripoint_south_west };
9097 for( const tripoint &impassable_diagonal : diagonals ) {
9098 if( impassable_adjacent.count( impassable_diagonal ) != 0 ) {
9099 //for every impassable diagonal found, we check if that diagonal terrain has at least two impassable neighbors that also neighbor point p
9100 int f = 0;
9101 for( const tripoint &l : points_in_radius( impassable_diagonal, 1 ) ) {
9102 if( impassable_adjacent.count( l ) != 0 ) {
9103 f++;
9104 }
9105 if( f > 2 ) {
9106 return true;
9107 }
9108 }
9109 }
9110 }
9111 }
9112 return false;
9113}
static constexpr tripoint tripoint_north_east
Definition: point.h:272
static constexpr tripoint tripoint_north_west
Definition: point.h:278
static constexpr tripoint tripoint_south_east
Definition: point.h:274
static constexpr tripoint tripoint_south_west
Definition: point.h:276

References impassable(), points_in_radius(), tripoint_north_east, tripoint_north_west, tripoint_south_east, and tripoint_south_west.

◆ is_divable() [1/2]

bool map::is_divable ( const tripoint p) const

Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing).

Parameters
pThe coordinate to look at.
Returns
true if the terrain can be dived into; false if not.

Definition at line 2619 of file map.cpp.

2620{
2621 return has_flag( "SWIMMABLE", p ) && has_flag( TFLAG_DEEP_WATER, p );
2622}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by enchantment::is_active(), is_divable(), and Creature::sees().

◆ is_divable() [2/2]

bool map::is_divable ( point  p) const
inline

Definition at line 1019 of file map.h.

1019 {
1020 return is_divable( tripoint( p, abs_sub.z ) );
1021 }
bool is_divable(const tripoint &p) const
Returns whether or not the terrain at the given location can be dived into (by monsters that can swim...
Definition: map.cpp:2619

References abs_sub, is_divable(), and tripoint::z.

◆ is_flammable()

bool map::is_flammable ( const tripoint p)

Returns true if there is a flammable item or field or the furn/terrain is flammable at p.

Definition at line 2703 of file map.cpp.

2704{
2705 if( flammable_items_at( p ) ) {
2706 return true;
2707 }
2708
2709 if( has_flag( "FLAMMABLE", p ) ) {
2710 return true;
2711 }
2712
2713 if( has_flag( "FLAMMABLE_ASH", p ) ) {
2714 return true;
2715 }
2716
2717 if( get_field_intensity( p, fd_web ) > 0 ) {
2718 return true;
2719 }
2720
2721 return false;
2722}
int get_field_intensity(const tripoint &p, const field_type_id &type) const
Get the intensity of a field entry (field_entry::intensity), if there is no field of that type,...
Definition: map.cpp:5477
bool flammable_items_at(const tripoint &p, int threshold=0)
Checks if there are any flammable items on the tile.
Definition: map.cpp:2686

References fd_web, flammable_items_at(), get_field_intensity(), and has_flag().

Referenced by Character::activate_bionic(), and activity_handlers::start_fire_do_turn().

◆ is_harvestable()

bool map::is_harvestable ( const tripoint pos) const

Returns true if point at pos is harvestable right now, with no extra tools.

Definition at line 1694 of file map.cpp.

1695{
1696 const auto &harvest_here = get_harvest( pos );
1697 return !harvest_here.is_null() && !harvest_here->empty();
1698}
const harvest_id & get_harvest(const tripoint &p) const
Returns the full harvest list, for spawning.
Definition: map.cpp:1628

References get_harvest(), and wrapped_vehicle::pos.

Referenced by npc::pick_up_item().

◆ is_last_ter_wall()

bool map::is_last_ter_wall ( bool  no_furn,
point  p,
point  max,
direction  dir 
) const

Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST.

Parameters
no_furnif true, the function will stop and return false if it encounters a furniture
pstarting coordinates of check
maxending coordinates of check
dirDirection of check
Returns
true if from x to xmax or y to ymax depending on direction all terrain is floor and the last terrain is a wall

Definition at line 2634 of file map.cpp.

2636{
2637 point mov;
2638 switch( dir ) {
2639 case direction::NORTH:
2640 mov.y = -1;
2641 break;
2642 case direction::SOUTH:
2643 mov.y = 1;
2644 break;
2645 case direction::WEST:
2646 mov.x = -1;
2647 break;
2648 case direction::EAST:
2649 mov.x = 1;
2650 break;
2651 default:
2652 break;
2653 }
2654 point p2( p );
2655 bool result = true;
2656 bool loop = true;
2657 while( ( loop ) && ( ( dir == direction::NORTH && p2.y >= 0 ) ||
2658 ( dir == direction::SOUTH && p2.y < max.y ) ||
2659 ( dir == direction::WEST && p2.x >= 0 ) ||
2660 ( dir == direction::EAST && p2.x < max.x ) ) ) {
2661 if( no_furn && has_furn( p2 ) ) {
2662 loop = false;
2663 result = false;
2664 } else if( !has_flag_ter( "FLAT", p2 ) ) {
2665 loop = false;
2666 if( !has_flag_ter( "WALL", p2 ) ) {
2667 result = false;
2668 }
2669 }
2670 p2.x += mov.x;
2671 p2.y += mov.y;
2672 }
2673 return result;
2674}

References EAST, has_flag_ter(), has_furn(), NORTH, SOUTH, WEST, point::x, and point::y.

Referenced by find_potential_computer_point().

◆ is_outside() [1/2]

◆ is_outside() [2/2]

bool map::is_outside ( point  p) const
inline

Definition at line 1009 of file map.h.

1009 {
1010 return is_outside( tripoint( p, abs_sub.z ) );
1011 }
bool is_outside(const tripoint &p) const
Definition: map.cpp:2624

References abs_sub, is_outside(), and tripoint::z.

◆ is_suspension_valid()

bool map::is_suspension_valid ( const tripoint point)

Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid.

Definition at line 3023 of file map.cpp.

3024{
3025 if( ter( point + tripoint_east ) != t_open_air
3026 && ter( point + tripoint_west ) != t_open_air ) {
3027 return true;
3028 }
3031 return true;
3032 }
3034 && ter( point + tripoint_north ) != t_open_air ) {
3035 return true;
3036 }
3039 return true;
3040 }
3041 return false;
3042}
static constexpr tripoint tripoint_north
Definition: point.h:271
static constexpr tripoint tripoint_west
Definition: point.h:277
static constexpr tripoint tripoint_east
Definition: point.h:273
static constexpr tripoint tripoint_south
Definition: point.h:275

References t_open_air, ter(), tripoint_east, tripoint_north, tripoint_north_east, tripoint_north_west, tripoint_south, tripoint_south_east, tripoint_south_west, and tripoint_west.

Referenced by collapse_invalid_suspension(), and update_suspension_cache().

◆ is_transparent()

bool map::is_transparent ( const tripoint p) const

Returns whether the tile at p is transparent(you can look past it).

Definition at line 690 of file lightmap.cpp.

691{
693}

References light_transparency(), and LIGHT_TRANSPARENCY_SOLID.

Referenced by ranged::execute_shaped_attack(), ranged::expected_coverage(), find_target_vehicle(), get_known_connections(), mattack::riotbot(), and shoot().

◆ is_wall_adjacent()

bool map::is_wall_adjacent ( const tripoint center) const

Definition at line 1832 of file map.cpp.

1833{
1834 for( const tripoint &p : points_in_radius( center, 1 ) ) {
1835 if( p != center && impassable( p ) ) {
1836 return true;
1837 }
1838 }
1839 return false;
1840}

References center, impassable(), and points_in_radius().

Referenced by ma_requirements::is_valid_character().

◆ is_water_shallow_current() [1/2]

bool map::is_water_shallow_current ( const tripoint p) const

Definition at line 2614 of file map.cpp.

2615{
2616 return has_flag( "CURRENT", p ) && !has_flag( TFLAG_DEEP_WATER, p );
2617}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by is_water_shallow_current(), and iexamine::quern_examine().

◆ is_water_shallow_current() [2/2]

bool map::is_water_shallow_current ( point  p) const
inline

Definition at line 1023 of file map.h.

1023 {
1025 }
bool is_water_shallow_current(const tripoint &p) const
Definition: map.cpp:2614

References abs_sub, is_water_shallow_current(), and tripoint::z.

◆ light_at()

lit_level map::light_at ( const tripoint p) const

Definition at line 656 of file lightmap.cpp.

657{
658 if( !inbounds( p ) ) {
659 return lit_level::DARK; // Out of bounds
660 }
661
662 const auto &map_cache = get_cache_ref( p.z );
663 const auto &lm = map_cache.lm;
664 const auto &sm = map_cache.sm;
665 if( sm[p.x][p.y] >= LIGHT_SOURCE_BRIGHT ) {
666 return lit_level::BRIGHT;
667 }
668
669 const float max_light = lm[p.x][p.y].max();
670 if( max_light >= LIGHT_AMBIENT_LIT ) {
671 return lit_level::LIT;
672 }
673
674 if( max_light >= LIGHT_AMBIENT_LOW ) {
675 return lit_level::LOW;
676 }
677
678 return lit_level::DARK;
679}

References BRIGHT, DARK, get_cache_ref(), inbounds(), LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIT, LOW, coords::sm, tripoint::x, tripoint::y, and tripoint::z.

Referenced by Creature::sees().

◆ light_transparency()

float map::light_transparency ( const tripoint p) const

Definition at line 695 of file lightmap.cpp.

696{
697 return get_cache_ref( p.z ).transparency_cache[p.x][p.y];
698}

References get_cache_ref(), level_cache::transparency_cache, tripoint::x, tripoint::y, and tripoint::z.

Referenced by generate_lightmap(), and is_transparent().

◆ load() [1/2]

void map::load ( const tripoint w,
bool  update_vehicles,
bool  pump_events = false 
)

Load submaps into grid.

This might create new submaps if the mapbuffer can not deliver the requested submap (as it does not exist on disc). This must be called before the map can be used at all!

Parameters
wglobal coordinates of the submap at grid[0]. This is in submap coordinates.
update_vehiclesIf true, add vehicles to the vehicle cache.
pump_eventsIf true, handle window events during loading. If you set this to true, do ensure that the map is not accessed before this function returns (for example, UIs that draw the map should be disabled).

Definition at line 6720 of file map.cpp.

6721{
6722 for( auto &traps : traplocs ) {
6723 traps.clear();
6724 }
6725 field_furn_locs.clear();
6727 set_abs_sub( w );
6728 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6729 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6730 loadn( point( gridx, gridy ), update_vehicle );
6731 if( pump_events ) {
6733 }
6734 }
6735 }
6737}
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
void loadn(const tripoint &grid, bool update_vehicles)
Definition: map.cpp:7102
input_manager inp_mngr
Definition: input.cpp:109

References field_furn_locs, inp_mngr, loadn(), my_MAPSIZE, input_manager::pump_events(), reset_vehicle_cache(), set_abs_sub(), submaps_with_active_items, and traplocs.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), debug_menu::debug(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), find_valid_teleporters_omt(), basecamp::form_crafting_inventory(), mission_start::kill_horde_master(), load(), game::load_map(), talk_function::loot_building(), editmap::mapgen_veh_destroy(), editmap::mapgen_veh_query(), MapExtras::mx_minefield(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), teleporter_list::place_avatar_overmap(), Character::place_corpse(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), debug_menu::spawn_nested_mapgen(), basecamp::start_relay_hide_site(), update_mapgen_function_json::update_map(), game::vertical_move(), and game::vertical_shift().

◆ load() [2/2]

void map::load ( const tripoint_abs_sm w,
bool  update_vehicles,
bool  pump_events = false 
)

Definition at line 6739 of file map.cpp.

6740{
6741 // TODO: fix point types
6742 load( w.raw(), update_vehicle, pump_events );
6743}
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6720

References load(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ loadn() [1/2]

void map::loadn ( const tripoint grid,
bool  update_vehicles 
)
protected

Definition at line 7102 of file map.cpp.

7103{
7104 // Cache empty overmap types
7105 static const oter_id rock( "empty_rock" );
7106 static const oter_id air( "open_air" );
7107
7108 const tripoint grid_abs_sub = abs_sub.xy() + grid;
7109 const size_t gridn = get_nonant( grid );
7110
7111 const int old_abs_z = abs_sub.z; // Ugly, but necessary at the moment
7112 abs_sub.z = grid.z;
7113
7114 submap *tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7115 if( tmpsub == nullptr ) {
7116 // It doesn't exist; we must generate it!
7117 dbg( DL::Info ) << "map::loadn: Missing mapbuffer data. Regenerating.";
7118
7119 // Each overmap square is two nonants; to prevent overlap, generate only at
7120 // squares divisible by 2.
7121 // TODO: fix point types
7122 const tripoint_abs_omt grid_abs_omt( sm_to_omt_copy( grid_abs_sub ) );
7123 const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt.raw() );
7124
7125 const oter_id terrain_type = overmap_buffer.ter( grid_abs_omt );
7126
7127 // Short-circuit if the map tile is uniform
7128 // TODO: Replace with json mapgen functions.
7129 if( terrain_type == air ) {
7130 generate_uniform( grid_abs_sub_rounded, t_open_air );
7131 } else if( terrain_type == rock ) {
7132 generate_uniform( grid_abs_sub_rounded, t_rock );
7133 } else {
7134 tinymap tmp_map;
7135 tmp_map.generate( grid_abs_sub_rounded, calendar::turn );
7136 }
7137
7138 // This is the same call to MAPBUFFER as above!
7139 tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7140 if( tmpsub == nullptr ) {
7141 debugmsg( "failed to generate a submap at %s", grid_abs_sub.to_string() );
7142 return;
7143 }
7144 }
7145
7146 // New submap changes the content of the map and all caches must be recalculated
7153 setsubmap( gridn, tmpsub );
7154 if( !tmpsub->active_items.empty() ) {
7155 submaps_with_active_items.emplace( grid_abs_sub );
7156 }
7157 if( tmpsub->field_count > 0 ) {
7158 get_cache( grid.z ).field_cache.set( grid.x + grid.y * MAPSIZE );
7159 }
7160 // Destroy bugged no-part vehicles
7161 auto &veh_vec = tmpsub->vehicles;
7162 for( auto iter = veh_vec.begin(); iter != veh_vec.end(); ) {
7163 vehicle *veh = iter->get();
7164 if( veh->part_count() > 0 ) {
7165 // Always fix submap coordinates for easier Z-level-related operations
7166 veh->sm_pos = grid;
7167 veh->attach();
7168 iter++;
7169 } else {
7171 if( veh->tracking_on ) {
7173 }
7174 dirty_vehicle_list.erase( veh );
7175 iter = veh_vec.erase( iter );
7176 }
7177 }
7178
7179 // Update vehicle data
7180 if( update_vehicles ) {
7181 auto &map_cache = get_cache( grid.z );
7182 for( const auto &veh : tmpsub->vehicles ) {
7183 // Only add if not tracking already.
7184 if( map_cache.vehicle_list.find( veh.get() ) == map_cache.vehicle_list.end() ) {
7185 map_cache.vehicle_list.insert( veh.get() );
7186 if( !veh->loot_zones.empty() ) {
7187 map_cache.zone_vehicles.insert( veh.get() );
7188 }
7189 add_vehicle_to_cache( veh.get() );
7190 }
7191 }
7192 }
7193
7194 actualize( grid );
7195
7196 abs_sub.z = old_abs_z;
7197}
void set_suspension_cache_dirty(const int zlev)
Definition: map.cpp:228
void generate(const tripoint &p, const time_point &when)
Definition: mapgen.cpp:107
void actualize(const tripoint &grid)
Fast forward a submap that has just been loading into this map.
Definition: map.cpp:7517
submap * lookup_submap(const tripoint &p)
Get a submap stored in this buffer.
Definition: mapbuffer.cpp:83
Definition: map.h:2060
std::unordered_multimap< point, zone_data > loot_zones
Definition: vehicle.h:1888
int part_count() const
Definition: vehicle.cpp:7079
void attach()
Definition: vehicle.h:765
point omt_to_sm_copy(point p)
static void generate_uniform(const tripoint &p, const ter_id &terrain_type)
Definition: map.cpp:7086
mapbuffer MAPBUFFER
Definition: mapbuffer.cpp:40

References abs_sub, submap::active_items, actualize(), add_vehicle_to_cache(), vehicle::attach(), dbg, debugmsg, dirty_vehicle_list, active_item_cache::empty(), level_cache::field_cache, submap::field_count, generate(), generate_uniform(), get_cache(), get_nonant(), grid, Info, mapbuffer::lookup_submap(), MAPBUFFER, MAPSIZE, omt_to_sm_copy(), overmap_buffer, vehicle::part_count(), coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), set_transparency_cache_dirty(), setsubmap(), vehicle::sm_pos, sm_to_omt_copy(), submaps_with_active_items, t_open_air, t_rock, overmapbuffer::ter(), tripoint::to_string(), vehicle::tracking_on, calendar::turn, submap::vehicles, tripoint::xy(), and tripoint::z.

Referenced by load(), loadn(), and shift().

◆ loadn() [2/2]

void map::loadn ( point  grid,
bool  update_vehicles 
)
inlineprotected

Definition at line 1673 of file map.h.

1673 {
1674 if( zlevels ) {
1675 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1676 loadn( tripoint( grid, gridz ), update_vehicles );
1677 }
1678
1679 // Note: we want it in a separate loop! It is a post-load cleanup
1680 // Since we're adding roofs, we want it to go up (from lowest to highest)
1681 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1682 add_roofs( tripoint( grid, gridz ) );
1683 }
1684 } else {
1685 loadn( tripoint( grid, abs_sub.z ), update_vehicles );
1686 }
1687 }
void add_roofs(const tripoint &grid)
Hacks in missing roofs.
Definition: map.cpp:7572

References abs_sub, add_roofs(), grid, loadn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

◆ make_active()

void map::make_active ( item_location loc)

Update an item's active status, for example when adding hot or perishable liquid to a container.

Definition at line 4524 of file map.cpp.

4525{
4526 item *target = loc.get_item();
4527
4528 // Trust but verify, don't let stinking callers set items active when they shouldn't be.
4529 if( !target->needs_processing() ) {
4530 return;
4531 }
4532 point l;
4533 submap *const current_submap = get_submap_at( loc.position(), l );
4534 cata::colony<item> &item_stack = current_submap->get_items( l );
4536
4537 if( current_submap->active_items.empty() ) {
4539 abs_sub.y + loc.position().y / SEEY, loc.position().z ) );
4540 }
4541 current_submap->active_items.add( *iter, l );
4542}
item * get_item()
Gets the selected item or nullptr.
tripoint position() const
Returns the position where the item is found.

References abs_sub, submap::active_items, active_item_cache::add(), active_item_cache::empty(), item_location::get_item(), submap::get_items(), item_stack::get_iterator_from_pointer(), get_submap_at(), item::needs_processing(), item_location::position(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by make_active(), and liquid_handler::perform_liquid_transfer().

◆ make_rubble() [1/3]

void map::make_rubble ( const tripoint p)
inline

Definition at line 1004 of file map.h.

1004 {
1005 make_rubble( p, f_rubble, t_dirt, false );
1006 }

References f_rubble, make_rubble(), and t_dirt.

◆ make_rubble() [2/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type 
)
inline

Definition at line 1001 of file map.h.

1001 {
1002 make_rubble( p, rubble_type, t_dirt, false );
1003 }

References make_rubble(), and t_dirt.

◆ make_rubble() [3/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
const ter_id floor_type,
bool  overwrite = false 
)

Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true.

Definition at line 2590 of file map.cpp.

2592{
2593 if( overwrite ) {
2594 ter_set( p, floor_type );
2595 furn_set( p, rubble_type );
2596 } else {
2597 // First see if there is existing furniture to destroy
2598 if( is_bashable_furn( p ) ) {
2599 destroy_furn( p, true );
2600 }
2601 // Leave the terrain alone unless it interferes with furniture placement
2602 if( impassable( p ) && is_bashable_ter( p ) ) {
2603 destroy( p, true );
2604 }
2605 // Check again for new terrain after potential destruction
2606 if( impassable( p ) ) {
2607 ter_set( p, floor_type );
2608 }
2609
2610 furn_set( p, rubble_type );
2611 }
2612}
void destroy_furn(const tripoint &p, bool silent=false)
Keeps bashing a square until there is no more furniture.
Definition: map.cpp:3749

References destroy(), destroy_furn(), furn_set(), impassable(), is_bashable_furn(), is_bashable_ter(), and ter_set().

Referenced by computer_session::action_irradiator(), computer_session::action_srcf_seal(), jmapgen_make_rubble::apply(), collapse_at(), draw_lab(), draw_mine(), computer_session::failure_pump_explode(), make_rubble(), mapgen_crater(), MapExtras::mx_helicopter(), and MapExtras::mx_portal().

◆ maptile_at() [1/2]

maptile map::maptile_at ( const tripoint p)

Definition at line 269 of file map.cpp.

270{
271 if( !inbounds( p ) ) {
272 return maptile( &null_submap, point_zero );
273 }
274
275 return maptile_at_internal( p );
276}
static submap null_submap
Definition: map.cpp:258

References inbounds(), maptile_at_internal(), null_submap, and point_zero.

◆ maptile_at() [2/2]

◆ maptile_at_internal() [1/2]

maptile map::maptile_at_internal ( const tripoint p)
private

Definition at line 286 of file map.cpp.

287{
288 point l;
289 submap *const sm = get_submap_at( p, l );
290
291 return maptile( sm, l );
292}

References get_submap_at(), and coords::sm.

◆ maptile_at_internal() [2/2]

maptile map::maptile_at_internal ( const tripoint p) const
private

Definition at line 278 of file map.cpp.

279{
280 point l;
281 submap *const sm = get_submap_at( p, l );
282
283 return maptile( sm, l );
284}

References get_submap_at(), and coords::sm.

Referenced by draw(), maptile_at(), maptile_has_bounds(), process_fields_in_submap(), route(), and spread_gas().

◆ maptile_has_bounds()

std::pair< tripoint, maptile > map::maptile_has_bounds ( const tripoint p,
bool  bounds_checked 
)
private

Definition at line 180 of file map_field.cpp.

181{
182 if( bounds_checked ) {
183 // We know that the point is in bounds
184 return {p, maptile_at_internal( p )};
185 }
186
187 return {p, maptile_at( p )};
188}

References maptile_at(), and maptile_at_internal().

Referenced by get_neighbors().

◆ max_volume()

units::volume map::max_volume ( const tripoint p)

Definition at line 4315 of file map.cpp.

4316{
4317 return i_at( p ).max_volume();
4318}
units::volume max_volume() const override
Maximum volume allowed here.
Definition: map.cpp:163

References i_at(), and map_stack::max_volume().

Referenced by advanced_inventory::print_items().

◆ mod_field_age()

time_duration map::mod_field_age ( const tripoint p,
const field_type_id type,
const time_duration offset 
)

Increment/decrement age of field entry at point.

Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5426 of file map.cpp.

5428{
5429 return set_field_age( p, type, offset, true );
5430}
time_duration set_field_age(const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
Set age of field entry at point.
Definition: map.cpp:5437

References set_field_age(), and type.

Referenced by game::process_artifact().

◆ mod_field_intensity()

int map::mod_field_intensity ( const tripoint p,
const field_type_id type,
int  offset 
)

Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5432 of file map.cpp.

5433{
5434 return set_field_intensity( p, type, offset, true );
5435}
int set_field_intensity(const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.
Definition: map.cpp:5450

References set_field_intensity(), and type.

Referenced by add_splatter(), and propagate_field().

◆ monster_in_field()

void map::monster_in_field ( monster z)
protected

Definition at line 1631 of file map_field.cpp.

1632{
1633 if( z.digging() ) {
1634 // Digging monsters are immune to fields
1635 return;
1636 }
1637 if( veh_at( z.pos() ) ) {
1638 // FIXME: Immune when in a vehicle for now.
1639 return;
1640 }
1641 field &curfield = get_field( z.pos() );
1642
1643 int dam = 0;
1644 // Iterate through all field effects on this tile.
1645 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1646 // later by the field processing, which will also adjust field_count accordingly.
1647 for( auto &field_list_it : curfield ) {
1648 field_entry &cur = field_list_it.second;
1649 if( !cur.is_field_alive() ) {
1650 continue;
1651 }
1652 const field_type_id cur_field_type = cur.get_field_type();
1653 if( cur_field_type == fd_web ) {
1654 if( !z.has_flag( MF_WEBWALK ) ) {
1655 z.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1656 cur.set_field_intensity( 0 );
1657 }
1658 }
1659 if( cur_field_type == fd_acid ) {
1660 if( !z.flies() ) {
1661 const int d = rng( cur.get_field_intensity(), cur.get_field_intensity() * 3 );
1662 z.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_ACID, d ) );
1663 z.check_dead_state();
1664 if( d > 0 ) {
1665 z.add_effect( effect_corroding, 1_turns * rng( d / 2, d * 2 ) );
1666 }
1667 }
1668
1669 }
1670 if( cur_field_type == fd_sap ) {
1671 z.moves -= cur.get_field_intensity() * 5;
1673 }
1674 if( cur_field_type == fd_sludge ) {
1675 if( !z.digs() && !z.flies() &&
1676 !z.has_flag( MF_SLUDGEPROOF ) ) {
1677 z.moves -= cur.get_field_intensity() * 300;
1678 cur.set_field_intensity( 0 );
1679 }
1680 }
1681 if( cur_field_type == fd_fire ) {
1682 // TODO: MATERIALS Use fire resistance
1683 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1684 return;
1685 }
1686 // TODO: Replace the section below with proper json values
1688 dam += 3;
1689 }
1690 if( z.made_of( material_id( "veggy" ) ) ) {
1691 dam += 12;
1692 }
1694 dam += 20;
1695 }
1697 dam += -20;
1698 }
1699 if( z.flies() ) {
1700 dam -= 15;
1701 }
1702 dam -= z.get_armor_type( DT_HEAT, bodypart_id( "torso" ) );
1703
1704 if( cur.get_field_intensity() == 1 ) {
1705 dam += rng( 2, 6 );
1706 } else if( cur.get_field_intensity() == 2 ) {
1707 dam += rng( 6, 12 );
1708 if( !z.flies() ) {
1709 z.moves -= 20;
1710 if( dam > 0 ) {
1711 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1712 }
1713 }
1714 } else if( cur.get_field_intensity() == 3 ) {
1715 dam += rng( 10, 20 );
1716 if( !z.flies() || one_in( 3 ) ) {
1717 z.moves -= 40;
1718 if( dam > 0 ) {
1719 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1720 }
1721 }
1722 }
1723 }
1724 if( cur_field_type == fd_smoke ) {
1725 if( !z.has_flag( MF_NO_BREATHE ) ) {
1726 if( cur.get_field_intensity() == 3 ) {
1727 z.moves -= rng( 10, 20 );
1728 }
1729 // Plants suffer from smoke even worse
1730 if( z.made_of( material_id( "veggy" ) ) ) {
1731 z.moves -= rng( 1, cur.get_field_intensity() * 12 );
1732 }
1733 }
1734
1735 }
1736 if( cur_field_type == fd_tear_gas ) {
1738 if( cur.get_field_intensity() == 3 ) {
1739 z.add_effect( effect_stunned, rng( 1_minutes, 2_minutes ) );
1740 dam += rng( 4, 10 );
1741 } else if( cur.get_field_intensity() == 2 ) {
1742 z.add_effect( effect_stunned, rng( 5_turns, 10_turns ) );
1743 dam += rng( 2, 5 );
1744 } else {
1745 z.add_effect( effect_stunned, rng( 1_turns, 5_turns ) );
1746 }
1747 if( z.made_of( material_id( "veggy" ) ) ) {
1748 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1749 dam += cur.get_field_intensity() * rng( 8, 14 );
1750 }
1751 if( z.has_flag( MF_SEES ) ) {
1752 z.add_effect( effect_blind, cur.get_field_intensity() * 8_turns );
1753 }
1754 }
1755
1756 }
1757 if( cur_field_type == fd_relax_gas ) {
1759 z.add_effect( effect_stunned, rng( cur.get_field_intensity() * 4_turns,
1760 cur.get_field_intensity() * 8_turns ) );
1761 }
1762 }
1763 if( cur_field_type == fd_dazzling ) {
1764 if( z.has_flag( MF_SEES ) && !z.has_flag( MF_ELECTRONIC ) ) {
1765 z.add_effect( effect_blind, cur.get_field_intensity() * 12_turns );
1766 z.add_effect( effect_stunned, cur.get_field_intensity() * rng( 5_turns, 12_turns ) );
1767 }
1768
1769 }
1770 if( cur_field_type == fd_toxic_gas ) {
1771 if( !z.has_flag( MF_NO_BREATHE ) ) {
1772 dam += cur.get_field_intensity();
1773 z.moves -= cur.get_field_intensity();
1774 }
1775
1776 }
1777 if( cur_field_type == fd_nuke_gas ) {
1778 if( !z.has_flag( MF_NO_BREATHE ) ) {
1779 if( cur.get_field_intensity() == 3 ) {
1780 z.moves -= rng( 60, 120 );
1781 dam += rng( 30, 50 );
1782 } else if( cur.get_field_intensity() == 2 ) {
1783 z.moves -= rng( 20, 50 );
1784 dam += rng( 10, 25 );
1785 } else {
1786 z.moves -= rng( 0, 15 );
1787 dam += rng( 0, 12 );
1788 }
1789 if( z.made_of( material_id( "veggy" ) ) ) {
1790 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1791 dam *= cur.get_field_intensity();
1792 }
1793 }
1794
1795 }
1796 if( cur_field_type == fd_flame_burst ) {
1797 // TODO: MATERIALS Use fire resistance
1798 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1799 return;
1800 }
1802 dam += 3;
1803 }
1804 if( z.made_of( material_id( "veggy" ) ) ) {
1805 dam += 12;
1806 }
1808 dam += 50;
1809 }
1811 dam += -25;
1812 }
1813 dam += rng( 0, 8 );
1814 z.moves -= 20;
1815 }
1816 if( cur_field_type == fd_electricity ) {
1817 // We don't want to increase dam, but deal a separate hit so that it can apply effects
1818 z.deal_damage( nullptr, bodypart_id( "torso" ),
1819 damage_instance( DT_ELECTRIC, rng( 1, cur.get_field_intensity() * 3 ) ) );
1820 }
1821 if( cur_field_type == fd_fatigue ) {
1822 if( rng( 0, 2 ) < cur.get_field_intensity() ) {
1823 dam += cur.get_field_intensity();
1824 teleport::teleport( z );
1825 }
1826 }
1827 if( cur_field_type == fd_incendiary ) {
1828 // TODO: MATERIALS Use fire resistance
1829 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1830 return;
1831 }
1833 dam += 3;
1834 }
1835 if( z.made_of( material_id( "veggy" ) ) ) {
1836 dam += 12;
1837 }
1839 dam += 20;
1840 }
1842 dam += -5;
1843 }
1844
1845 if( cur.get_field_intensity() == 1 ) {
1846 dam += rng( 2, 6 );
1847 } else if( cur.get_field_intensity() == 2 ) {
1848 dam += rng( 6, 12 );
1849 z.moves -= 20;
1850 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1851 z.add_effect( effect_onfire, rng( 8_turns, 12_turns ) );
1852 }
1853 } else if( cur.get_field_intensity() == 3 ) {
1854 dam += rng( 10, 20 );
1855 z.moves -= 40;
1856 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1857 z.add_effect( effect_onfire, rng( 12_turns, 16_turns ) );
1858 }
1859 }
1860 }
1861 if( cur_field_type == fd_fungal_haze ) {
1862 if( !z.type->in_species( FUNGUS ) &&
1863 !z.type->has_flag( MF_NO_BREATHE ) &&
1864 !z.make_fungus() ) {
1865 // Don't insta-kill jabberwocks, that's silly
1866 const int intensity = cur.get_field_intensity();
1867 z.moves -= rng( 10 * intensity, 30 * intensity );
1868 dam += rng( 0, 10 * intensity );
1869 }
1870 }
1871 if( cur_field_type == fd_fungicidal_gas ) {
1872 if( z.type->in_species( FUNGUS ) ) {
1873 const int intensity = cur.get_field_intensity();
1874 z.moves -= rng( 10 * intensity, 30 * intensity );
1875 dam += rng( 4, 7 * intensity );
1876 }
1877 }
1878 if( cur_field_type == fd_insecticidal_gas ) {
1879 if( z.type->in_species( INSECT ) || z.type->in_species( SPIDER ) ) {
1880 const int intensity = cur.get_field_intensity();
1881 z.moves -= rng( 10 * intensity, 30 * intensity );
1882 dam += rng( 4, 7 * intensity );
1883 }
1884 }
1885 }
1886
1887 if( dam > 0 ) {
1888 z.apply_damage( nullptr, bodypart_id( "torso" ), dam, true );
1889 z.check_dead_state();
1890 }
1891}
static const std::set< material_id > cmat_flammable
Definition: creature.h:482
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:881
static const std::set< material_id > cmat_flesh
Definition: creature.h:480
int moves
Definition: creature.h:578
static const std::set< material_id > cmat_fleshnveg
Definition: creature.h:481
static const std::set< material_id > cmat_flameres
Definition: creature.h:483
bool has_flag(m_flag f) const override
Definition: monster.cpp:898
bool digs() const
Definition: monster.cpp:940
bool made_of_any(const std::set< material_id > &ms) const override
Definition: monster.cpp:992
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1840
bool make_fungus()
Makes this monster into a fungus version Returns false if no such monster exists Returns true if mons...
Definition: monster.cpp:2626
const tripoint & pos() const override
Definition: monster.cpp:256
bool made_of(const material_id &m) const override
Definition: monster.cpp:987
const mtype * type
Definition: monster.h:477
int get_armor_type(damage_type dt, bodypart_id bp) const override
Definition: monster.cpp:1901
bool flies() const
Definition: monster.cpp:945
bool digging() const override
Definition: monster.cpp:930
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_HEAT
Definition: damage.h:28
field_type_id fd_incendiary
Definition: field_type.cpp:372
field_type_id fd_toxic_gas
Definition: field_type.cpp:347
field_type_id fd_tear_gas
Definition: field_type.cpp:348
field_type_id fd_sludge
Definition: field_type.cpp:344
field_type_id fd_nuke_gas
Definition: field_type.cpp:349
field_type_id fd_dazzling
Definition: field_type.cpp:361
field_type_id fd_electricity
Definition: field_type.cpp:353
field_type_id fd_fungal_haze
Definition: field_type.cpp:374
field_type_id fd_smoke
Definition: field_type.cpp:346
field_type_id fd_sap
Definition: field_type.cpp:343
field_type_id fd_fungicidal_gas
Definition: field_type.cpp:383
field_type_id fd_acid
Definition: field_type.cpp:342
field_type_id fd_flame_burst
Definition: field_type.cpp:352
field_type_id fd_relax_gas
Definition: field_type.cpp:373
field_type_id fd_fatigue
Definition: field_type.cpp:354
field_type_id fd_insecticidal_gas
Definition: field_type.cpp:384
static const efftype_id effect_blind("blind")
static const species_id FUNGUS("FUNGUS")
static const species_id INSECT("INSECT")
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_stunned("stunned")
static const species_id SPIDER("SPIDER")
static const efftype_id effect_onfire("onfire")
@ MF_SEES
Definition: mtype.h:67
@ MF_FIREY
Definition: mtype.h:103
@ MF_WEBWALK
Definition: mtype.h:85
@ MF_FIREPROOF
Definition: mtype.h:99
@ MF_SLUDGEPROOF
Definition: mtype.h:100
@ MF_ELECTRONIC
Definition: mtype.h:105
@ MF_NO_BREATHE
Definition: mtype.h:123
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
bool has_flag(m_flag flag) const
Definition: mtype.cpp:75
bool in_species(const species_id &spec) const
Definition: mtype.cpp:122

References monster::add_effect(), monster::apply_damage(), Creature::check_dead_state(), Creature::cmat_flameres, Creature::cmat_flammable, Creature::cmat_flesh, Creature::cmat_fleshnveg, Creature::deal_damage(), monster::digging(), monster::digs(), DT_ACID, DT_ELECTRIC, DT_HEAT, effect_blind, effect_corroding, effect_onfire, effect_stunned, effect_webbed, fd_acid, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_nuke_gas, fd_relax_gas, fd_sap, fd_sludge, fd_smoke, fd_tear_gas, fd_toxic_gas, fd_web, monster::flies(), FUNGUS, monster::get_armor_type(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), monster::has_flag(), mtype::has_flag(), mtype::in_species(), INSECT, field_entry::is_field_alive(), LIQUID, monster::made_of(), monster::made_of_any(), monster::make_fungus(), MF_ELECTRONIC, MF_FIREPROOF, MF_FIREY, MF_NO_BREATHE, MF_SEES, MF_SLUDGEPROOF, MF_WEBWALK, Creature::moves, num_bp, one_in(), monster::pos(), rng(), field_entry::set_field_intensity(), SPIDER, teleport::teleport(), monster::type, and veh_at().

Referenced by creature_in_field().

◆ mop_spills()

bool map::mop_spills ( const tripoint p)

Remove moppable fields/items at this location.

Parameters
pthe location
Returns
true if anything moppable was there, false otherwise.

Definition at line 2855 of file map.cpp.

2856{
2857 bool retval = false;
2858
2859 if( !has_flag( "LIQUIDCONT", p ) && !has_flag( "SEALED", p ) ) {
2860 auto items = i_at( p );
2861 auto new_end = std::remove_if( items.begin(), items.end(), []( const item & it ) {
2862 return it.made_of( LIQUID );
2863 } );
2864 retval = new_end != items.end();
2865 while( new_end != items.end() ) {
2866 new_end = items.erase( new_end );
2867 }
2868 }
2869
2870 field &fld = field_at( p );
2871 static const std::vector<field_type_id> to_check = {
2872 fd_blood,
2880 fd_bile,
2881 fd_slime,
2882 fd_sludge
2883 };
2884 for( field_type_id fid : to_check ) {
2885 retval |= fld.remove_field( fid );
2886 }
2887
2888 if( const optional_vpart_position vp = veh_at( p ) ) {
2889 vehicle *const veh = &vp->vehicle();
2890 std::vector<int> parts_here = veh->parts_at_relative( vp->mount(), true );
2891 for( auto &elem : parts_here ) {
2892 if( veh->part( elem ).blood > 0 ) {
2893 veh->part( elem ).blood = 0;
2894 retval = true;
2895 }
2896 //remove any liquids that somehow didn't fall through to the ground
2897 vehicle_stack here = veh->get_items( elem );
2898 auto new_end = std::remove_if( here.begin(), here.end(), []( const item & it ) {
2899 return it.made_of( LIQUID );
2900 } );
2901 retval |= ( new_end != here.end() );
2902 while( new_end != here.end() ) {
2903 new_end = here.erase( new_end );
2904 }
2905 }
2906 } // if veh != 0
2907 return retval;
2908}
bool remove_field(const field_type_id &field_to_remove)
Removes the field entry with a type equal to the field_type_id parameter.
Definition: field.cpp:219
iterator erase(const_iterator it) override
Definition: vehicle.cpp:231
std::vector< int > parts_at_relative(point dp, bool use_cache) const
Definition: vehicle.cpp:2417
field_type_id fd_gibs_insect
Definition: field_type.cpp:365
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_bile
Definition: field_type.cpp:337
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_gibs_veggy
Definition: field_type.cpp:339
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_slime
Definition: field_type.cpp:341
field_type_id fd_gibs_invertebrate
Definition: field_type.cpp:366
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References item_stack::begin(), vehicle_part::blood, item_stack::end(), vehicle_stack::erase(), fd_bile, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, fd_gibs_flesh, fd_gibs_insect, fd_gibs_invertebrate, fd_gibs_veggy, fd_slime, fd_sludge, field_at(), vehicle::get_items(), has_flag(), i_at(), vehicle::part(), vehicle::parts_at_relative(), field::remove_field(), veh_at(), and vehicle::vehicle().

◆ move_cost() [1/2]

int map::move_cost ( const tripoint p,
const vehicle ignored_vehicle = nullptr 
) const

Calculate the cost to move past the tile at p.

The move cost is determined by various obstacles, such as terrain, vehicles and furniture.

Note
Movement costs for players and zombies both use this function.
Returns
The return value is interpreted as follows:
Move Cost Meaning
0 Impassable. Use passable/impassable to check for this.
n > 0 x*n turns to move past this

Definition at line 1844 of file map.cpp.

1845{
1846 if( !inbounds( p ) ) {
1847 return 0;
1848 }
1849
1850 const furn_t &furniture = furn( p ).obj();
1851 const ter_t &terrain = ter( p ).obj();
1852 const optional_vpart_position vp = veh_at( p );
1853 vehicle *const veh = ( !vp || &vp->vehicle() == ignored_vehicle ) ? nullptr : &vp->vehicle();
1854 const int part = veh ? vp->part_index() : -1;
1855
1856 return move_cost_internal( furniture, terrain, veh, part );
1857}
int move_cost_internal(const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
Internal versions of public functions to avoid checking same variables multiple times.
Definition: map.cpp:1807

References furn(), furniture, inbounds(), move_cost_internal(), int_id< T >::obj(), ter(), terrain, and veh_at().

Referenced by character_funcs::base_comfort_value(), activity_handlers::burrow_finish(), combined_movecost(), draw_mine(), game::grabbed_veh_move(), place_trap_actor::is_allowed(), is_solid_neighbor(), mine_activity(), npc::move_away_from(), move_cost(), obstacle_coverage(), passable(), activity_handlers::pickaxe_finish(), game::print_terrain_info(), reachable_flood_steps(), deploy_furn_actor::use(), game::vertical_move(), and game::walk_move().

◆ move_cost() [2/2]

int map::move_cost ( point  p,
const vehicle ignored_vehicle = nullptr 
) const
inline

Definition at line 562 of file map.h.

562 {
563 return move_cost( tripoint( p, abs_sub.z ), ignored_vehicle );
564 }

References abs_sub, move_cost(), and tripoint::z.

◆ move_cost_internal()

int map::move_cost_internal ( const furn_t furniture,
const ter_t terrain,
const vehicle veh,
int  vpart 
) const
private

Internal versions of public functions to avoid checking same variables multiple times.

They lack safety checks, because their callers already do those.

Definition at line 1807 of file map.cpp.

1809{
1810 if( terrain.movecost == 0 || ( furniture.id && furniture.movecost < 0 ) ) {
1811 return 0;
1812 }
1813
1814 if( veh != nullptr ) {
1815 const vpart_position vp( const_cast<vehicle &>( *veh ), vpart );
1816 if( vp.obstacle_at_part() ) {
1817 return 0;
1818 } else if( vp.part_with_feature( VPFLAG_AISLE, true ) ) {
1819 return 2;
1820 } else {
1821 return 8;
1822 }
1823 }
1824
1825 if( furniture.id ) {
1826 return std::max( terrain.movecost + furniture.movecost, 0 );
1827 }
1828
1829 return std::max( terrain.movecost, 0 );
1830}

References furniture, vpart_position::obstacle_at_part(), vpart_position::part_with_feature(), terrain, and VPFLAG_AISLE.

Referenced by move_cost(), route(), and update_pathfinding_cache().

◆ move_cost_ter_furn() [1/2]

int map::move_cost_ter_furn ( const tripoint p) const

Similar behavior to move_cost(), but ignores vehicles.

Definition at line 1869 of file map.cpp.

1870{
1871 if( !inbounds( p ) ) {
1872 return 0;
1873 }
1874
1875 point l;
1876 submap *const current_submap = get_submap_at( p, l );
1877
1878 const int tercost = current_submap->get_ter( l ).obj().movecost;
1879 if( tercost == 0 ) {
1880 return 0;
1881 }
1882
1883 const int furncost = current_submap->get_furn( l ).obj().movecost;
1884 if( furncost < 0 ) {
1885 return 0;
1886 }
1887
1888 const int cost = tercost + furncost;
1889 return cost > 0 ? cost : 0;
1890}

References submap::get_furn(), get_submap_at(), submap::get_ter(), inbounds(), map_data_common_t::movecost, and int_id< T >::obj().

Referenced by move_cost_ter_furn(), vehicle::part_collision(), passable_ter_furn(), and vehicle_wheel_traction().

◆ move_cost_ter_furn() [2/2]

int map::move_cost_ter_furn ( point  p) const
inline

Definition at line 579 of file map.h.

579 {
580 return move_cost_ter_furn( tripoint( p, abs_sub.z ) );
581 }
int move_cost_ter_furn(const tripoint &p) const
Similar behavior to move_cost(), but ignores vehicles.
Definition: map.cpp:1869

References abs_sub, move_cost_ter_furn(), and tripoint::z.

◆ move_vehicle()

vehicle * map::move_vehicle ( vehicle veh,
const tripoint dp,
const tileray facing 
)

Definition at line 579 of file map.cpp.

580{
581 if( dp == tripoint_zero ) {
582 debugmsg( "Empty displacement vector" );
583 return &veh;
584 } else if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ) {
585 debugmsg( "Invalid displacement vector: %d, %d, %d", dp.x, dp.y, dp.z );
586 return &veh;
587 }
588 // Split the movement into horizontal and vertical for easier processing
589 if( dp.xy() != point_zero && dp.z != 0 ) {
590 vehicle *const new_pointer = move_vehicle( veh, tripoint( dp.xy(), 0 ), facing );
591 if( !new_pointer ) {
592 return nullptr;
593 }
594
595 vehicle *const result = move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), facing );
596 if( !result ) {
597 return nullptr;
598 }
599
600 result->is_falling = false;
601 return result;
602 }
603 const bool vertical = dp.z != 0;
604 // Ensured by the splitting above
605 assert( vertical == ( dp.xy() == point_zero ) );
606
607 const int target_z = dp.z + veh.sm_pos.z;
608 if( target_z < -OVERMAP_DEPTH || target_z > OVERMAP_HEIGHT ) {
609 return &veh;
610 }
611
612 veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() );
613
614 // cancel out any movement of the vehicle due only to a change in pivot
615 tripoint dp1 = dp - veh.pivot_displacement();
616
617 if( !vertical ) {
618 veh.adjust_zlevel( 1, dp1 );
619 }
620
621 int impulse = 0;
622
623 std::vector<veh_collision> collisions;
624
625 // Find collisions
626 // Velocity of car before collision
627 // Split into vertical and horizontal movement
628 const int &coll_velocity = vertical ? veh.vertical_velocity : veh.velocity;
629 const int velocity_before = coll_velocity;
630 if( velocity_before == 0 && !veh.is_rotorcraft() && !veh.is_flying_in_air() ) {
631 debugmsg( "%s tried to move %s with no velocity",
632 veh.name, vertical ? "vertically" : "horizontally" );
633 return &veh;
634 }
635
636 bool veh_veh_coll_flag = false;
637 // Try to collide multiple times
638 size_t collision_attempts = 10;
639 do {
640 collisions.clear();
641 veh.collision( collisions, dp1, false );
642
643 // Vehicle collisions
644 std::map<vehicle *, std::vector<veh_collision> > veh_collisions;
645 for( auto &coll : collisions ) {
646 if( coll.type != veh_coll_veh ) {
647 continue;
648 }
649
650 veh_veh_coll_flag = true;
651 // Only collide with each vehicle once
652 veh_collisions[ static_cast<vehicle *>( coll.target ) ].push_back( coll );
653 }
654
655 for( auto &pair : veh_collisions ) {
656 impulse += vehicle_vehicle_collision( veh, *pair.first, pair.second );
657 }
658
659 // Non-vehicle collisions
660 for( const auto &coll : collisions ) {
661 if( coll.type == veh_coll_veh ) {
662 continue;
663 }
664 if( coll.part > veh.part_count() ||
665 veh.part( coll.part ).removed ) {
666 continue;
667 }
668
669 point collision_point = veh.part( coll.part ).mount;
670 const int coll_dmg = coll.imp;
671 // Shock damage, if the target part is a rotor treat as an aimed hit.
672 if( veh.part_info( coll.part ).rotor_diameter() > 0 ) {
673 veh.damage( coll.part, coll_dmg, DT_BASH, true );
674 } else {
675 impulse += coll_dmg;
676 veh.damage( coll.part, coll_dmg, DT_BASH );
677 veh.damage_all( coll_dmg / 2, coll_dmg, DT_BASH, collision_point );
678 }
679 }
680
681 // prevent vehicle bouncing after the first collision
682 if( vertical && velocity_before < 0 && coll_velocity > 0 ) {
683 veh.vertical_velocity = 0; // also affects `coll_velocity` and thus exits the loop
684 }
685
686 } while( collision_attempts-- > 0 && coll_velocity != 0 &&
687 sgn( coll_velocity ) == sgn( velocity_before ) &&
688 !collisions.empty() && !veh_veh_coll_flag );
689
690 const int velocity_after = coll_velocity;
691 bool can_move = velocity_after != 0 && sgn( velocity_after ) == sgn( velocity_before );
692 if( dp.z != 0 && veh.is_rotorcraft() ) {
693 can_move = true;
694 }
695 units::angle coll_turn = 0_degrees;
696 if( impulse > 0 ) {
697 coll_turn = shake_vehicle( veh, velocity_before, facing.dir() );
698 veh.stop_autodriving();
699 const int volume = std::min<int>( 100, std::sqrt( impulse ) );
700 // TODO: Center the sound at weighted (by impulse) average of collisions
702 false, "smash_success", "hit_vehicle" );
703 }
704
705 if( veh_veh_coll_flag ) {
706 // Break here to let the hit vehicle move away
707 return nullptr;
708 }
709
710 // If not enough wheels, mess up the ground a bit.
711 if( !vertical && !veh.valid_wheel_config() && !veh.is_in_water() && !veh.is_flying_in_air() &&
712 dp.z == 0 ) {
713 veh.velocity += veh.velocity < 0 ? 2000 : -2000;
714 for( const auto &p : veh.get_points() ) {
715 const ter_id &pter = ter( p );
716 if( pter == t_dirt || pter == t_grass ) {
717 ter_set( p, t_dirtmound );
718 }
719 }
720 }
721
722 const units::angle last_turn_dec = 1_degrees;
723 if( veh.last_turn < 0_degrees ) {
724 veh.last_turn += last_turn_dec;
725 if( veh.last_turn > -last_turn_dec ) {
726 veh.last_turn = 0_degrees;
727 }
728 } else if( veh.last_turn > 0_degrees ) {
729 veh.last_turn -= last_turn_dec;
730 if( veh.last_turn < last_turn_dec ) {
731 veh.last_turn = 0_degrees;
732 }
733 }
734
735 Character &player_character = get_player_character();
736 const bool seen = sees_veh( player_character, veh, false );
737
738 if( can_move || ( vertical && veh.is_falling ) ) {
739 // Accept new direction
740 if( veh.skidding ) {
741 veh.face.init( veh.turn_dir );
742 } else {
743 veh.face = facing;
744 }
745
746 veh.move = facing;
747 if( coll_turn != 0_degrees ) {
748 veh.skidding = true;
749 veh.turn( coll_turn );
750 }
751 veh.on_move();
752 // Actually change position
753 displace_vehicle( veh, dp1 );
754 veh.shift_zlevel();
755 } else if( !vertical ) {
756 veh.stop();
757 }
759 // If the PC is in the currently moved vehicle, adjust the
760 // view offset.
761 if( g->u.controlling_vehicle && veh_pointer_or_null( veh_at( g->u.pos() ) ) == &veh ) {
762 g->calc_driving_offset( &veh );
763 if( veh.skidding && can_move ) {
764 // TODO: Make skid recovery in air hard
766 }
767 }
768 // Now we're gonna handle traps we're standing on (if we're still moving).
769 if( !vertical && can_move ) {
770 const auto wheel_indices = veh.wheelcache; // Don't use a reference here, it causes a crash.
771
772 // Values to deal with crushing items.
773 // The math needs to be floating-point to work, so the values might as well be.
774 const float vehicle_grounded_wheel_area = static_cast<int>( vehicle_wheel_traction( veh, true ) );
775 const float weight_to_damage_factor = 0.05; // Nobody likes a magic number.
776 const float vehicle_mass_kg = to_kilogram( veh.total_mass() );
777
778 for( auto &w : wheel_indices ) {
779 const tripoint wheel_p = veh.global_part_pos3( w );
780 if( one_in( 2 ) && displace_water( wheel_p ) ) {
781 sounds::sound( wheel_p, 4, sounds::sound_t::movement, _( "splash!" ), false,
782 "environment", "splash" );
783 }
784
785 veh.handle_trap( wheel_p, w );
786 if( !has_flag( "SEALED", wheel_p ) ) {
787 const float wheel_area = veh.part( w ).wheel_area();
788
789 // Damage is calculated based on the weight of the vehicle,
790 // The area of it's wheels, and the area of the wheel running over the items.
791 // This number is multiplied by weight_to_damage_factor to get reasonable results, damage-wise.
792 const int wheel_damage = static_cast<int>( ( ( wheel_area / vehicle_grounded_wheel_area ) *
793 vehicle_mass_kg ) * weight_to_damage_factor );
794
795 //~ %1$s: vehicle name
796 smash_items( wheel_p, wheel_damage, string_format( _( "weight of %1$s" ), veh.disp_name() ),
797 false );
798 }
799 }
800 }
801 if( veh.is_towing() ) {
802 veh.do_towing_move();
803 // veh.do_towing_move() may cancel towing, so we need to recheck is_towing here
804 if( veh.is_towing() && veh.tow_data.get_towed()->tow_cable_too_far() ) {
805 add_msg( m_info, _( "A towing cable snaps off of %s." ),
806 veh.tow_data.get_towed()->disp_name() );
807 veh.tow_data.get_towed()->invalidate_towing( true );
808 }
809 }
810 // Redraw scene, but only if the player is not engaged in an activity and
811 // the vehicle was seen before or after the move.
812 if( !player_character.activity && ( seen || sees_veh( player_character, veh, true ) ) ) {
813 g->invalidate_main_ui_adaptor();
817 }
818 return &veh;
819}
player_activity activity
Definition: character.h:1551
float vehicle_wheel_traction(const vehicle &veh, bool ignore_movement_modifiers=false) const
void smash_items(const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
Tries to smash the items at the given tripoint.
Definition: map.cpp:3072
bool displace_vehicle(vehicle &veh, const tripoint &dp)
Definition: map.cpp:1183
bool displace_water(const tripoint &dp)
Definition: map.cpp:1343
units::angle shake_vehicle(vehicle &veh, int velocity_before, units::angle direction)
vehicle * move_vehicle(vehicle &veh, const tripoint &dp, const tileray &facing)
Definition: map.cpp:579
float vehicle_vehicle_collision(vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
Definition: map.cpp:821
void init(point ad)
Definition: tileray.cpp:27
vehicle * get_towed() const
Definition: vehicle.h:159
void turn(units::angle deg)
void adjust_zlevel(int idir=0, const tripoint &offset=tripoint_zero)
bool is_rotorcraft() const
is the vehicle flying? is it a rotorcraft?
Definition: vehicle.cpp:4198
std::set< tripoint > & get_points(bool force_refresh=false)
Definition: vehicle.cpp:6762
bool skidding
Definition: vehicle.h:2024
units::angle last_turn
Definition: vehicle.h:1954
bool is_towing() const
Definition: vehicle.cpp:6036
int vertical_velocity
Definition: vehicle.h:1947
int velocity
Definition: vehicle.h:1943
void damage_all(int dmg1, int dmg2, damage_type type, point impact)
Definition: vehicle.cpp:6444
bool valid_wheel_config() const
Definition: vehicle.cpp:4461
units::mass total_mass() const
Definition: vehicle.cpp:3307
std::vector< int > wheelcache
Definition: vehicle.h:1843
void check_falling_or_floating()
bool is_flying_in_air() const
Definition: vehicle.cpp:4208
towing_data tow_data
Definition: vehicle.h:1969
point pivot_point() const
Definition: vehicle.cpp:5828
int damage(int p, int dmg, damage_type type=DT_BASH, bool aimed=true)
Definition: vehicle.cpp:6365
bool is_in_water(bool deep_water=false) const
is the vehicle mostly in water or mostly on fairly dry land?
Definition: vehicle.cpp:4223
void possibly_recover_from_skid()
tileray move
Definition: vehicle.h:1975
void stop_autodriving(bool apply_brakes=true)
bool collision(std::vector< veh_collision > &colls, const tripoint &dp, bool just_detect, bool bash_floor=false)
void precalc_mounts(int idir, units::angle dir, point pivot)
Definition: vehicle.cpp:3151
bool tow_cable_too_far() const
Definition: vehicle.cpp:6165
std::string disp_name() const
void handle_trap(const tripoint &p, int part)
bool is_falling
Definition: vehicle.h:2030
void shift_zlevel()
units::angle turn_dir
Definition: vehicle.h:1952
point pivot_displacement() const
Definition: vehicle.cpp:3345
void do_towing_move()
Definition: vehicle.cpp:5937
void on_move()
Definition: vehicle.cpp:5278
int rotor_diameter() const
Definition: veh_type.cpp:909
@ m_info
Definition: enums.h:265
constexpr int sgn(const T x)
Definition: enums.h:8
static bool sees_veh(const Creature &c, vehicle &veh, bool force_recalc)
Definition: map.cpp:571
void redraw_invalidated()
Redraw all invalidated windows without invalidating the top window.
Definition: ui_manager.cpp:394
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16
constexpr value_type to_kilogram(const quantity< value_type, mass_in_milligram_tag > &v)
Definition: units_mass.h:73
void refresh_display()
Make changes made to the display visible to the user immediately.
static constexpr tripoint tripoint_zero
Definition: point.h:259
int wheel_area() const
Get wheel diameter times wheel width (inches^2) or return 0 if part is not wheel.
bool removed
true if this part is removed.
Definition: vehicle.h:411
point mount
mount point: x is on the forward/backward axis, y is on the left/right axis
Definition: vehicle.h:368
@ veh_coll_veh
Definition: vehicle.h:102

References _, Character::activity, add_msg(), vehicle::adjust_zlevel(), vehicle::check_falling_or_floating(), vehicle::collision(), sounds::combat, vehicle::damage(), vehicle::damage_all(), debugmsg, tileray::dir(), vehicle::disp_name(), displace_vehicle(), displace_water(), vehicle::do_towing_move(), DT_BASH, vehicle::face, g, get_player_character(), vehicle::get_points(), towing_data::get_towed(), vehicle::global_part_pos3(), vehicle::global_pos3(), vehicle::handle_trap(), has_flag(), tileray::init(), inp_mngr, vehicle::invalidate_towing(), vehicle::is_falling, vehicle::is_flying_in_air(), vehicle::is_in_water(), vehicle::is_rotorcraft(), vehicle::is_towing(), vehicle::last_turn, m_info, vehicle_part::mount, vehicle::move, move_vehicle(), sounds::movement, vehicle::name, vehicle::on_move(), one_in(), OVERMAP_HEIGHT, vehicle::part(), vehicle::part_count(), vehicle::part_info(), vehicle::pivot_displacement(), vehicle::pivot_point(), point_zero, vehicle::possibly_recover_from_skid(), vehicle::precalc_mounts(), input_manager::pump_events(), ui_manager::redraw_invalidated(), refresh_display(), vehicle_part::removed, vpart_info::rotor_diameter(), sees_veh(), sgn(), shake_vehicle(), vehicle::shift_zlevel(), vehicle::skidding, vehicle::sm_pos, smash_items(), sounds::sound(), vehicle::stop(), vehicle::stop_autodriving(), string_format(), t_dirt, t_dirtmound, t_grass, ter(), ter_set(), units::to_kilogram(), vehicle::total_mass(), vehicle::tow_cable_too_far(), vehicle::tow_data, tripoint_zero, vehicle::turn(), vehicle::turn_dir, vehicle::valid_wheel_config(), veh_at(), veh_coll_veh, veh_pointer_or_null(), vehicle_vehicle_collision(), vehicle_wheel_traction(), vehicle::velocity, vehicle::vertical_velocity, vehicle_part::wheel_area(), vehicle::wheelcache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ name() [1/2]

◆ name() [2/2]

std::string map::name ( point  p)
inline

Definition at line 779 of file map.h.

779 {
780 return name( tripoint( p, abs_sub.z ) );
781 }

References abs_sub, name(), and tripoint::z.

◆ obscured_by_vehicle_rotation()

bool map::obscured_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.

Definition at line 6630 of file map.cpp.

6631{
6632 if( !inbounds( from ) || !inbounds( to ) ) {
6633 return false;
6634 }
6635
6636 if( from.z != to.z ) {
6637 //Split it into two checks, one for each z level
6638 tripoint flattened = {from.xy(), to.z};
6639 if( obscured_by_vehicle_rotation( flattened, to ) ) {
6640 return true;
6641 }
6642 }
6643
6644 point delta = to.xy() - from.xy();
6645
6646 auto cache = get_cache( from.z ).vehicle_obscured_cache;
6647
6648 if( delta == point_north_west ) {
6649 return cache[from.x][from.y].nw;
6650 }
6651
6652 if( delta == point_north_east ) {
6653 return cache[from.x][from.y].ne;
6654 }
6655
6656 if( delta == point_south_west ) {
6657 return cache[to.x][to.y].ne;
6658 }
6659 if( delta == point_south_east ) {
6660 return cache[to.x][to.y].nw;
6661 }
6662
6663 return false;
6664}
bool obscured_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.
Definition: map.cpp:6630
bool nw
Definition: map.h:297

References get_cache(), inbounds(), diagonal_blocks::nw, obscured_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obscured_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by obscured_by_vehicle_rotation(), mattack::riotbot(), Creature::sees(), and sees().

◆ obstacle_coverage()

int map::obstacle_coverage ( const tripoint loc1,
const tripoint loc2 
) const

Returns coverage of target in relation to the observer.

Target is loc2, observer is loc1. First tile from the target is an obstacle, which has the coverage value. If there's no obstacle adjacent to the target - no coverage.

Definition at line 6327 of file map.cpp.

6328{
6329 // Can't hide if you are standing on furniture, or non-flat slowing-down terrain tile.
6330 if( furn( loc2 ).obj().id || ( move_cost( loc2 ) > 2 && !has_flag_ter( TFLAG_FLAT, loc2 ) ) ) {
6331 return 0;
6332 }
6333 const point a( std::abs( loc1.x - loc2.x ) * 2, std::abs( loc1.y - loc2.y ) * 2 );
6334 int offset = std::min( a.x, a.y ) - ( std::max( a.x, a.y ) / 2 );
6335 tripoint obstaclepos;
6336 bresenham( loc2, loc1, offset, 0, [&obstaclepos]( const tripoint & new_point ) {
6337 // Only adjacent tile between you and enemy is checked for cover.
6338 obstaclepos = new_point;
6339 return false;
6340 } );
6341 if( const auto obstacle_f = furn( obstaclepos ) ) {
6342 return obstacle_f->coverage;
6343 }
6344 if( const auto vp = veh_at( obstaclepos ) ) {
6345 if( vp->obstacle_at_part() ) {
6346 return 60;
6347 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6348 return 45;
6349 }
6350 }
6351 return ter( obstaclepos )->coverage;
6352}
@ TFLAG_FLAT
Definition: mapdata.h:317

References a, bresenham(), map_data_common_t::coverage, furn(), has_flag_ter(), move_cost(), ter(), TFLAG_FLAT, veh_at(), VPFLAG_AISLE, tripoint::x, and tripoint::y.

Referenced by Creature::sees().

◆ obstacle_name()

std::string map::obstacle_name ( const tripoint p)

Returns the name of the obstacle at p that might be blocking movement/projectiles/etc.

Note that this only accounts for vehicles, terrain, and furniture.

Definition at line 1399 of file map.cpp.

1400{
1401 if( const std::optional<vpart_reference> vp = veh_at( p ).obstacle_at_part() ) {
1402 return vp->info().name();
1403 }
1404 return name( p );
1405}

References name(), and veh_at().

Referenced by mattack::longswipe(), avatar_action::move(), and teleport::teleport().

◆ obstructed_by_vehicle_rotation()

bool map::obstructed_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.

Definition at line 6593 of file map.cpp.

6594{
6595 if( !inbounds( from ) || !inbounds( to ) ) {
6596 return false;
6597 }
6598
6599 if( from.z != to.z ) {
6600 //Split it into two checks, one for each z level
6601 tripoint flattened = {from.xy(), to.z};
6602 if( obstructed_by_vehicle_rotation( flattened, to ) ) {
6603 return true;
6604 }
6605 }
6606
6607 point delta = to.xy() - from.xy();
6608
6609 auto cache = get_cache( from.z ).vehicle_obstructed_cache;
6610
6611 if( delta == point_north_west ) {
6612 return cache[from.x][from.y].nw;
6613 }
6614
6615 if( delta == point_north_east ) {
6616 return cache[from.x][from.y].ne;
6617 }
6618
6619 if( delta == point_south_west ) {
6620 return cache[to.x][to.y].ne;
6621 }
6622 if( delta == point_south_east ) {
6623 return cache[to.x][to.y].nw;
6624 }
6625
6626 return false;
6627}
diagonal_blocks vehicle_obstructed_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:339

References get_cache(), inbounds(), diagonal_blocks::nw, obstructed_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obstructed_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by add_splatter_trail(), mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), monster::can_squeeze_to(), choose_adjacent_highlight(), clear_path(), clear_shot_reach(), mattack::flame(), game::fling_creature(), gas_can_spread_to(), handle_action_menu(), in_spell_aoe(), explosion_handler::ExplosionProcess::is_occluded(), game::knockback(), explosion_handler::legacy_blast(), mattack::longswipe(), avatar_action::move(), explosion_handler::ExplosionProcess::move_entity(), npc::move_to(), obstructed_by_vehicle_rotation(), game::peek(), npc::pick_up_item(), process_fields_in_submap(), projectile_attack(), spell_effect::projectile_attack(), propagate_field(), mattack::ranged_pull(), Character::reach_attack(), route_adjacent(), area_expander::run(), scatter_chunks(), sinkhole_safety_roll(), spell_effect::spell_effect_cone(), and test_passable().

◆ on_vehicle_moved()

void map::on_vehicle_moved ( int  smz)

Callback invoked when a vehicle has moved.

Definition at line 464 of file map.cpp.

465{
469 set_floor_cache_dirty( smz + 1 );
471}

References set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), and set_transparency_cache_dirty().

Referenced by vehicle::act_on_map(), and displace_vehicle().

◆ open_door()

bool map::open_door ( const tripoint p,
bool  inside,
bool  check_only = false 
)

Definition at line 3976 of file map.cpp.

3977{
3978 avatar &you = get_avatar();
3979 const auto &ter = this->ter( p ).obj();
3980 const auto &furn = this->furn( p ).obj();
3981 if( ter.open ) {
3982 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3983 return false;
3984 }
3985
3986 if( !check_only ) {
3987 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3988 "open_door", ter.id.str() );
3989 ter_set( p, ter.open );
3990
3991 if( ( you.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || you.has_artifact_with( AEP_SCHIZO ) )
3992 && one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) {
3993 tripoint mp = p + -2 * you.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z );
3994 g->spawn_hallucination( mp );
3995 }
3996 }
3997
3998 return true;
3999 } else if( furn.open ) {
4000 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
4001 return false;
4002 }
4003
4004 if( !check_only ) {
4005 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
4006 "open_door", furn.id.str() );
4007 furn_set( p, furn.open );
4008 }
4009
4010 return true;
4011 } else if( const optional_vpart_position vp = veh_at( p ) ) {
4012 int openable = vp->vehicle().next_part_to_open( vp->part_index(), true );
4013 if( openable >= 0 ) {
4014 if( !check_only ) {
4015 if( !vp->vehicle().handle_potential_theft( you ) ) {
4016 return false;
4017 }
4018 vp->vehicle().open_all_at( openable );
4019 }
4020
4021 return true;
4022 }
4023
4024 return false;
4025 }
4026
4027 return false;
4028}
avatar & get_avatar()
Definition: avatar.cpp:104
virtual bool has_artifact_with(art_effect_passive effect) const
Definition: character.cpp:3196
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:101
Definition: avatar.h:55
@ AEP_SCHIZO
Definition: enums.h:128

References _, AEP_SCHIZO, furn(), furn_set(), g, get_avatar(), Character::has_artifact_with(), has_flag(), Character::has_trait(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), one_in(), Character::pos(), sounds::sound(), string_id< T >::str(), ter(), ter_set(), veh_at(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by can_interact_at(), npc::can_open_door(), iexamine::door_peephole(), monster::move(), avatar_action::move(), npc::move_to(), open(), and rate_location().

◆ operator=() [1/2]

map & map::operator= ( const map )
delete

◆ operator=() [2/2]

map & map::operator= ( map &&  )
default

◆ partial_con_at()

partial_con * map::partial_con_at ( const tripoint p)

Definition at line 5251 of file map.cpp.

5252{
5253 if( !inbounds( p ) ) {
5254 return nullptr;
5255 }
5256 point l;
5257 submap *const current_submap = get_submap_at( p, l );
5258 auto it = current_submap->partial_constructions.find( tripoint( l, p.z ) );
5259 if( it != current_submap->partial_constructions.end() ) {
5260 return &it->second;
5261 }
5262 return nullptr;
5263}
std::map< tripoint, partial_con > partial_constructions
Definition: submap.h:219

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by activity_handlers::build_do_turn(), can_do_activity_there(), complete_construction(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_locations(), player_activity::get_progress_message(), place_construction(), game::print_trap_info(), and iexamine::trap().

◆ partial_con_remove()

void map::partial_con_remove ( const tripoint p)

Definition at line 5265 of file map.cpp.

5266{
5267 if( !inbounds( p ) ) {
5268 return;
5269 }
5270 point l;
5271 submap *const current_submap = get_submap_at( p, l );
5272 current_submap->partial_constructions.erase( tripoint( l, p.z ) );
5273}

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by complete_construction(), and iexamine::trap().

◆ partial_con_set()

void map::partial_con_set ( const tripoint p,
const partial_con con 
)

Definition at line 5275 of file map.cpp.

5276{
5277 if( !inbounds( p ) ) {
5278 return;
5279 }
5280 point l;
5281 submap *const current_submap = get_submap_at( p, l );
5282 if( !current_submap->partial_constructions.emplace( tripoint( l, p.z ), con ).second ) {
5283 debugmsg( "set partial con on top of terrain which already has a partial con" );
5284 }
5285}

References debugmsg, get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by construction_activity(), and place_construction().

◆ passable() [1/2]

◆ passable() [2/2]

bool map::passable ( point  p) const
inline

Definition at line 570 of file map.h.

570 {
571 return passable( tripoint( p, abs_sub.z ) );
572 }

References abs_sub, passable(), and tripoint::z.

◆ passable_ter_furn()

bool map::passable_ter_furn ( const tripoint p) const

Definition at line 1897 of file map.cpp.

1898{
1899 return move_cost_ter_furn( p ) != 0;
1900}

References move_cost_ter_furn().

Referenced by impassable_ter_furn(), and avatar_action::move().

◆ pl_line_of_sight()

bool map::pl_line_of_sight ( const tripoint t,
int  max_range 
) const

Uses the map cache to tell if the player could see the given square.

pl_sees implies pl_line_of_sight Used for infrared.

Definition at line 830 of file lightmap.cpp.

831{
832 if( !inbounds( t ) ) {
833 return false;
834 }
835
836 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
837 // Out of range!
838 return false;
839 }
840
841 const auto &map_cache = get_cache_ref( t.z );
842 // Any epsilon > 0 is fine - it means lightmap processing visited the point
843 return map_cache.seen_cache[t.x][t.y] > 0.0f ||
844 map_cache.camera_cache[t.x][t.y] > 0.0f;
845}

References g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by get_heat_radiation(), and Character::sees_with_infrared().

◆ pl_sees()

bool map::pl_sees ( const tripoint t,
int  max_range 
) const

Whether the player character (g->u) can see the given square (local map coordinates).

This only checks the transparency of the path to the target, the light level is not checked.

Parameters
tTarget point to look at
max_rangeAll squares that are further away than this are invisible. Ignored if smaller than 0.

Definition at line 812 of file lightmap.cpp.

813{
814 if( !inbounds( t ) ) {
815 return false;
816 }
817
818 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
819 return false; // Out of range!
820 }
821
822 const auto &map_cache = get_cache_ref( t.z );
823 const apparent_light_info a = apparent_light_helper( map_cache, t );
824 const float light_at_player = map_cache.lm[g->u.posx()][g->u.posy()].max();
825 return !a.obstructed &&
826 ( a.apparent_light >= g->u.get_vision_threshold( light_at_player ) ||
827 map_cache.sm[t.x][t.y] > 0.0 );
828}

References a, apparent_light_helper(), g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), sounds::process_sound_markers(), and Character::sees().

◆ place_gas_pump() [1/2]

void map::place_gas_pump ( point  p,
int  charges 
)

Definition at line 5481 of file mapgen.cpp.

5482{
5483 place_gas_pump( p, charges, one_in( 4 ) ? "diesel" : "gasoline" );
5484}
void place_gas_pump(point p, int charges, const std::string &fuel_type)
Definition: mapgen.cpp:5473

References one_in(), and place_gas_pump().

◆ place_gas_pump() [2/2]

void map::place_gas_pump ( point  p,
int  charges,
const std::string &  fuel_type 
)

Definition at line 5473 of file mapgen.cpp.

5474{
5475 item fuel( fuel_type, calendar::start_of_cataclysm );
5476 fuel.charges = charges;
5477 add_item( p, fuel );
5478 ter_set( p, ter_id( fuel.fuel_pump_terrain() ) );
5479}

References add_item(), item::charges, item::fuel_pump_terrain(), calendar::start_of_cataclysm, ter_id, and ter_set().

Referenced by jmapgen_gaspump::apply(), mapgen_tutorial(), and place_gas_pump().

◆ place_items() [1/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const tripoint p1,
const tripoint p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)

Place items from item group in the rectangle f - t.

Several items may be spawned on different places. Several items may spawn at once (at one place) when the item group says so (uses item_group::items_from which may return several items at once).

Parameters
locCurrent location of items to be placed
chanceChance for more items. A chance of 100 creates 1 item all the time, otherwise it's the chance that more items will be created (place items until the random roll with that chance fails). The chance is used for the first item as well, so it may not spawn an item at all. Values <= 0 or > 100 are invalid.
p1One corner of rectangle in which to spawn items
p2Second corner of rectangle in which to spawn items
ongrassIf false the items won't spawn on flat terrain (grass, floor, ...).
turnThe birthday that the created items shall have.
magazinepercentage chance item will contain the default magazine
ammopercentage chance item will be filled with default ammo
Returns
vector containing all placed items

Definition at line 5546 of file mapgen.cpp.

5550{
5551 // TODO: implement for 3D
5552 std::vector<item *> res;
5553
5554 if( chance > 100 || chance <= 0 ) {
5555 debugmsg( "map::place_items() called with an invalid chance (%d)", chance );
5556 return res;
5557 }
5558 if( !item_group::group_is_defined( loc ) ) {
5559 // TODO: fix point types
5561 const oter_id &oid = overmap_buffer.ter( omt );
5562 debugmsg( "place_items: invalid item group '%s', om_terrain = '%s' (%s)",
5563 loc.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() );
5564 return res;
5565 }
5566
5567 const float spawn_rate = get_option<float>( "ITEM_SPAWNRATE" );
5568 int spawn_count = roll_remainder( chance * spawn_rate / 100.0f );
5569 for( int i = 0; i < spawn_count; i++ ) {
5570 // Might contain one item or several that belong together like guns & their ammo
5571 int tries = 0;
5572 auto is_valid_terrain = [this, ongrass]( point p ) {
5573 auto &terrain = ter( p ).obj();
5574 return terrain.movecost == 0 &&
5575 !terrain.has_flag( "PLACE_ITEM" ) &&
5576 !ongrass &&
5577 !terrain.has_flag( "FLAT" );
5578 };
5579
5580 point p;
5581 do {
5582 p.x = rng( p1.x, p2.x );
5583 p.y = rng( p1.y, p2.y );
5584 tries++;
5585 } while( is_valid_terrain( p ) && tries < 20 );
5586 if( tries < 20 ) {
5587 auto put = put_items_from_loc( loc, tripoint( p, abs_sub.z ), turn );
5588 res.insert( res.end(), put.begin(), put.end() );
5589 }
5590 }
5591 for( auto e : res ) {
5592 if( e->is_tool() || e->is_gun() || e->is_magazine() ) {
5593 if( rng( 0, 99 ) < magazine && !e->magazine_integral() && !e->magazine_current() ) {
5594 e->put_in( item( e->magazine_default(), e->birthday() ) );
5595 }
5596 if( rng( 0, 99 ) < ammo && e->ammo_remaining() == 0 ) {
5597 e->ammo_set( e->ammo_default(), e->ammo_capacity() );
5598 }
5599 }
5600 }
5601 return res;
5602}
constexpr scale omt
Definition: coordinates.h:32
bool group_is_defined(const item_group_id &group_id)
Check whether an item group of the given id exists.
Definition: item_group.cpp:603

References abs_sub, string_id< T >::c_str(), debugmsg, get_abs_sub(), oter_t::get_mapgen_id(), item_group::group_is_defined(), int_id< T >::id(), int_id< T >::obj(), coords::omt, overmap_buffer, put_items_from_loc(), rng(), roll_remainder(), sm_to_omt_copy(), ter(), overmapbuffer::ter(), terrain, calendar::turn, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by jmapgen_item_group::apply(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), mapgen_ants_food(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_hive(), mapgen_parking_lot(), mapgen_road(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_military(), MapExtras::mx_minefield(), MapExtras::mx_roadblock(), MapExtras::mx_roadworks(), MapExtras::mx_science(), MapExtras::mx_supplydrop(), place_items(), place_vending(), mission_start::ranch_nurse_8(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), and science_room().

◆ place_items() [2/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
point  p1,
point  p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)
inline

Definition at line 1309 of file map.h.

1311 {
1312 return place_items( loc, chance, tripoint( p1, abs_sub.z ), tripoint( p2, abs_sub.z ), ongrass,
1313 turn, magazine, ammo );
1314 }

References abs_sub, place_items(), calendar::turn, and tripoint::z.

◆ place_npc()

character_id map::place_npc ( point  p,
const string_id< npc_template > &  type,
bool  force = false 
)

Definition at line 5514 of file mapgen.cpp.

5515{
5516 if( !force && !get_option<bool>( "STATIC_NPC" ) ) {
5517 return character_id(); //Do not generate an npc.
5518 }
5519 shared_ptr_fast<npc> temp = make_shared_fast<npc>();
5520 temp->load_npc_template( type );
5521 temp->spawn_at_precise( { abs_sub.xy() }, { p, abs_sub.z } );
5522 temp->toggle_trait( trait_NPC_STATIC_NPC );
5523 overmap_buffer.insert_npc( temp );
5524 return temp->getID();
5525}
void insert_npc(const shared_ptr_fast< npc > &who)
Adds the npc to an overmap ( based on the npcs current location ) and stores it there.
static const trait_id trait_NPC_STATIC_NPC("NPC_STATIC_NPC")
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References abs_sub, character_id, overmapbuffer::insert_npc(), overmap_buffer, trait_NPC_STATIC_NPC, type, tripoint::xy(), and tripoint::z.

Referenced by jmapgen_npc::apply(), mapgen_hive(), MapExtras::mx_bandits_block(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), mission_start::ranch_nurse_9(), and place_npc_iuse::use().

◆ place_spawns()

void map::place_spawns ( const mongroup_id group,
int  chance,
point  p1,
point  p2,
float  density,
bool  individual = false,
bool  friendly = false,
const std::string &  name = "NONE",
int  mission_id = -1 
)

Definition at line 5423 of file mapgen.cpp.

5426{
5427 if( !group.is_valid() ) {
5428 // TODO: fix point types
5430 const oter_id &oid = overmap_buffer.ter( omt );
5431 debugmsg( "place_spawns: invalid mongroup '%s', om_terrain = '%s' (%s)", group.c_str(),
5432 oid.id().c_str(), oid->get_mapgen_id().c_str() );
5433 return;
5434 }
5435
5436 // Set chance to be 1 or less to guarantee spawn, else set higher than 1
5437 if( !one_in( chance ) ) {
5438 return;
5439 }
5440
5441 float spawn_density = 1.0f;
5443 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
5444 } else {
5445 spawn_density = get_option< float >( "SPAWN_DENSITY" );
5446 }
5447
5448 float multiplier = density * spawn_density;
5449 // Only spawn 1 creature if individual flag set, else scale by density
5450 float thenum = individual ? 1 : ( multiplier * rng_float( 10.0f, 50.0f ) );
5451 int num = roll_remainder( thenum );
5452
5453 // GetResultFromGroup decrements num
5454 while( num > 0 ) {
5455 int tries = 10;
5456 point p;
5457
5458 // Pick a spot for the spawn
5459 do {
5460 p.x = rng( p1.x, p2.x );
5461 p.y = rng( p1.y, p2.y );
5462 tries--;
5463 } while( impassable( p ) && tries > 0 );
5464
5465 // Pick a monster type
5467
5468 add_spawn( spawn_details.name, spawn_details.pack_size, { p, abs_sub.z },
5469 friendly, -1, mission_id, name );
5470 }
5471}
group
Definition: sounds.h:125

References add_spawn(), string_id< T >::c_str(), debugmsg, friendly, get_abs_sub(), oter_t::get_mapgen_id(), MonsterGroupManager::GetResultFromGroup(), int_id< T >::id(), impassable(), MonsterGroupManager::is_animal(), name(), MonsterGroupResult::name, num, coords::omt, one_in(), overmap_buffer, MonsterGroupResult::pack_size, rng(), rng_float(), roll_remainder(), sm_to_omt_copy(), overmapbuffer::ter(), point::x, and point::y.

Referenced by add_monsters(), jmapgen_monster_group::apply(), create_anomaly(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_military(), MapExtras::mx_pond(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), MapExtras::mx_science(), and science_room().

◆ place_toilet()

void map::place_toilet ( point  p,
int  charges = 6 * 4 
)

Definition at line 5486 of file mapgen.cpp.

5487{
5488 item water( "water", calendar::start_of_cataclysm );
5489 water.charges = charges;
5490 add_item( p, water );
5491 furn_set( p, f_toilet );
5492}

References add_item(), item::charges, f_toilet, furn_set(), and calendar::start_of_cataclysm.

Referenced by jmapgen_toilet::apply(), and mapf::formatted_set_simple().

◆ place_vending()

void map::place_vending ( point  p,
const item_group_id type,
bool  reinforced = false 
)

Definition at line 5494 of file mapgen.cpp.

5495{
5496 if( reinforced ) {
5498 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5499 } else {
5500 if( one_in( 2 ) ) {
5501 furn_set( p, f_vending_o );
5502 for( const auto &loc : points_in_radius( { p, abs_sub.z }, 1 ) ) {
5503 if( one_in( 4 ) ) {
5504 spawn_item( loc, "glass_shard", rng( 1, 2 ) );
5505 }
5506 }
5507 } else {
5508 furn_set( p, f_vending_c );
5509 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5510 }
5511 }
5512}
furn_id f_vending_o
Definition: mapdata.cpp:1111
furn_id f_vending_reinforced
Definition: mapdata.cpp:1134
furn_id f_vending_c
Definition: mapdata.cpp:1111

References abs_sub, f_vending_c, f_vending_o, f_vending_reinforced, furn_set(), one_in(), place_items(), points_in_radius(), rng(), spawn_item(), calendar::start_of_cataclysm, type, and tripoint::z.

Referenced by jmapgen_vending_machine::apply().

◆ player_in_field()

void map::player_in_field ( player u)
protected

Definition at line 1223 of file map_field.cpp.

1224{
1225 // A copy of the current field for reference. Do not add fields to it, use map::add_field
1226 field &curfield = get_field( u.pos() );
1227 // Are we inside?
1228 bool inside = false;
1229 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1230 // and what part of the vehicle we need to deal with.
1231 if( u.in_vehicle ) {
1232 if( const optional_vpart_position vp = veh_at( u.pos() ) ) {
1233 inside = vp->is_inside();
1234 }
1235 }
1236
1237 // Iterate through all field effects on this tile.
1238 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1239 // later by the field processing, which will also adjust field_count accordingly.
1240 for( auto &field_list_it : curfield ) {
1241 field_entry &cur = field_list_it.second;
1242 if( !cur.is_field_alive() ) {
1243 continue;
1244 }
1245
1246 // Do things based on what field effect we are currently in.
1247 const field_type_id ft = cur.get_field_type();
1248 if( ft == fd_web ) {
1249 // If we are in a web, can't walk in webs or are in a vehicle, get webbed maybe.
1250 // Moving through multiple webs stacks the effect.
1251 if( !u.has_trait( trait_WEB_WALKER ) && !u.in_vehicle ) {
1252 // Between 5 and 15 minus your current web level.
1253 u.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1254 // It is spent.
1255 cur.set_field_intensity( 0 );
1256 continue;
1257 // If you are in a vehicle destroy the web.
1258 // It should of been destroyed when you ran over it anyway.
1259 } else if( u.in_vehicle ) {
1260 cur.set_field_intensity( 0 );
1261 continue;
1262 }
1263 }
1264 if( ft == fd_acid ) {
1265 // Assume vehicles block acid damage entirely,
1266 // you're certainly not standing in it.
1267 if( !u.in_vehicle && !u.has_trait( trait_ACIDPROOF ) ) {
1268 int total_damage = 0;
1269 total_damage += burn_body_part( u, cur, bp_foot_l, 2 );
1270 total_damage += burn_body_part( u, cur, bp_foot_r, 2 );
1271 const bool on_ground = u.is_on_ground();
1272 if( on_ground ) {
1273 // Apply the effect to the remaining body parts
1274 total_damage += burn_body_part( u, cur, bp_leg_l, 2 );
1275 total_damage += burn_body_part( u, cur, bp_leg_r, 2 );
1276 total_damage += burn_body_part( u, cur, bp_hand_l, 2 );
1277 total_damage += burn_body_part( u, cur, bp_hand_r, 2 );
1278 total_damage += burn_body_part( u, cur, bp_torso, 2 );
1279 // Less arms = less ability to keep upright
1280 if( ( !u.has_two_arms() && one_in( 4 ) ) || one_in( 2 ) ) {
1281 total_damage += burn_body_part( u, cur, bp_arm_l, 1 );
1282 total_damage += burn_body_part( u, cur, bp_arm_r, 1 );
1283 total_damage += burn_body_part( u, cur, bp_head, 1 );
1284 }
1285 }
1286
1287 if( on_ground && total_damage > 0 ) {
1288 u.add_msg_player_or_npc( m_bad, _( "The acid burns your body!" ),
1289 _( "The acid burns <npcname>s body!" ) );
1290 } else if( total_damage > 0 ) {
1291 u.add_msg_player_or_npc( m_bad, _( "The acid burns your legs and feet!" ),
1292 _( "The acid burns <npcname>s legs and feet!" ) );
1293 } else if( on_ground ) {
1294 u.add_msg_if_player( m_warning, _( "You're lying in a pool of acid" ) );
1295 } else {
1296 u.add_msg_if_player( m_warning, _( "You're standing in a pool of acid" ) );
1297 }
1298
1299 u.check_dead_state();
1300 }
1301 }
1302 if( ft == fd_sap ) {
1303 // Sap does nothing to cars.
1304 if( !u.in_vehicle ) {
1305 // Use up sap.
1307 }
1308 }
1309 if( ft == fd_sludge ) {
1310 // Sludge is on the ground, but you are above the ground when boarded on a vehicle
1311 if( !u.in_vehicle ) {
1312 u.add_msg_if_player( m_bad, _( "The sludge is thick and sticky. You struggle to pull free." ) );
1313 u.moves -= cur.get_field_intensity() * 300;
1314 cur.set_field_intensity( 0 );
1315 }
1316 }
1317 if( ft == fd_fire ) {
1318 // Heatsink or suit prevents ALL fire damage.
1320
1321 // To modify power of a field based on... whatever is relevant for the effect.
1322 int adjusted_intensity = cur.get_field_intensity();
1323 // Burn the player. Less so if you are in a car or ON a car.
1324 if( u.in_vehicle ) {
1325 if( inside ) {
1326 adjusted_intensity -= 2;
1327 } else {
1328 adjusted_intensity -= 1;
1329 }
1330 }
1331
1332 if( adjusted_intensity >= 1 ) {
1333 // Burn message by intensity
1334 static const std::array<std::string, 4> player_burn_msg = { {
1335 translate_marker( "You burn your legs and feet!" ),
1336 translate_marker( "You're burning up!" ),
1337 translate_marker( "You're set ablaze!" ),
1338 translate_marker( "Your whole body is burning!" )
1339 }
1340 };
1341 static const std::array<std::string, 4> npc_burn_msg = { {
1342 translate_marker( "<npcname> burns their legs and feet!" ),
1343 translate_marker( "<npcname> is burning up!" ),
1344 translate_marker( "<npcname> is set ablaze!" ),
1345 translate_marker( "<npcname>s whole body is burning!" )
1346 }
1347 };
1348 static const std::array<std::string, 4> player_warn_msg = { {
1349 translate_marker( "You're standing in a fire!" ),
1350 translate_marker( "You're waist-deep in a fire!" ),
1351 translate_marker( "You're surrounded by raging fire!" ),
1352 translate_marker( "You're lying in fire!" )
1353 }
1354 };
1355
1356 const int burn_min = adjusted_intensity;
1357 const int burn_max = 3 * adjusted_intensity + 3;
1358 std::list<bodypart_id> parts_burned;
1359 int msg_num = adjusted_intensity - 1;
1360 if( !u.is_on_ground() ) {
1361 switch( adjusted_intensity ) {
1362 case 3:
1363 parts_burned.push_back( bodypart_id( "hand_l" ) );
1364 parts_burned.push_back( bodypart_id( "hand_r" ) );
1365 parts_burned.push_back( bodypart_id( "arm_l" ) );
1366 parts_burned.push_back( bodypart_id( "arm_r" ) );
1367 /* fallthrough */
1368 case 2:
1369 parts_burned.push_back( bodypart_id( "torso" ) );
1370 /* fallthrough */
1371 case 1:
1372 parts_burned.push_back( bodypart_id( "foot_l" ) );
1373 parts_burned.push_back( bodypart_id( "foot_r" ) );
1374 parts_burned.push_back( bodypart_id( "leg_l" ) );
1375 parts_burned.push_back( bodypart_id( "leg_r" ) );
1376 }
1377 } else {
1378 // Lying in the fire is BAAAD news, hits every body part.
1379 msg_num = 3;
1380 const std::vector<bodypart_id> &all_parts = u.get_all_body_parts();
1381 // HACK: Skip num_bp part
1382 for( auto bp : all_parts ) {
1383 if( bp->token != num_bp ) {
1384 parts_burned.push_back( bp );
1385 }
1386 }
1387 }
1388
1389 int total_damage = 0;
1390 for( const bodypart_id part_burned : parts_burned ) {
1391 const dealt_damage_instance dealt = u.deal_damage( nullptr, part_burned,
1392 damage_instance( DT_HEAT, rng( burn_min, burn_max ) ) );
1393 total_damage += dealt.type_damage( DT_HEAT );
1394 }
1395 if( total_damage > 0 ) {
1396 u.add_msg_player_or_npc( m_bad, _( player_burn_msg[msg_num] ), _( npc_burn_msg[msg_num] ) );
1397 } else {
1398 u.add_msg_if_player( m_warning, _( player_warn_msg[msg_num] ) );
1399 }
1400 u.check_dead_state();
1401 }
1402 }
1403
1404 }
1405 if( ft == fd_tear_gas ) {
1406 // Tear gas will both give you teargas disease and/or blind you.
1407 if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
1408 u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
1409 }
1410 if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
1411 u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
1412 }
1413 }
1414 if( ft == fd_fungal_haze ) {
1415 if( !u.has_trait( trait_M_IMMUNE ) && ( !inside || one_in( 4 ) ) ) {
1416 u.add_env_effect( effect_fungus, bp_mouth, 4, 10_minutes, num_bp );
1417 u.add_env_effect( effect_fungus, bp_eyes, 4, 10_minutes, num_bp );
1418 }
1419 }
1420 if( ft == fd_dazzling ) {
1421 if( cur.get_field_intensity() > 1 || one_in( 5 ) ) {
1422 u.add_env_effect( effect_blind, bp_eyes, 10, 10_turns );
1423 } else {
1424 u.add_env_effect( effect_blind, bp_eyes, 2, 2_turns );
1425 }
1426 }
1427
1428 if( cur.extra_radiation_min() > 0 ) {
1429 // Get irradiated by the nuclear fallout.
1430 const float rads = rng( cur.extra_radiation_min() + 1,
1431 cur.extra_radiation_max() * ( cur.extra_radiation_max() + 1 ) );
1432 const bool rad_proof = !u.irradiate( rads );
1433 // TODO: Reduce damage for rad resistant?
1434 if( cur.radiation_hurt_damage_min() > 0 && !rad_proof ) {
1436 u.hurtall( rng( cur.radiation_hurt_damage_min(), cur.radiation_hurt_damage_max() ), nullptr );
1437 }
1438 }
1439 if( ft == fd_flame_burst ) {
1440 // A burst of flame? Only hits the legs and torso.
1441 if( !inside ) {
1442 // Fireballs can't touch you inside a car.
1443 // Heatsink or suit stops fire.
1444 if( !u.has_active_bionic( bio_heatsink ) &&
1446 u.add_msg_player_or_npc( m_bad, _( "You're torched by flames!" ),
1447 _( "<npcname> is torched by flames!" ) );
1448 u.deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1449 u.deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1450 u.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_HEAT, rng( 4, 9 ) ) );
1451 u.check_dead_state();
1452 } else {
1453 u.add_msg_player_or_npc( _( "These flames do not burn you." ),
1454 _( "Those flames do not burn <npcname>." ) );
1455 }
1456 }
1457 }
1458 if( ft == fd_electricity ) {
1459 // Small universal damage based on intensity, only if not electroproofed.
1460 if( !u.is_elec_immune() ) {
1461 int total_damage = 0;
1462 for( size_t i = 0; i < num_hp_parts; i++ ) {
1463 const bodypart_id bp = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id();
1464 const int dmg = rng( 1, cur.get_field_intensity() );
1465 total_damage += u.deal_damage( nullptr, bp, damage_instance( DT_ELECTRIC, dmg ) ).total_damage();
1466 }
1467
1468 if( total_damage > 0 ) {
1470 u.add_msg_player_or_npc( m_bad, _( "You're painfully electrocuted!" ),
1471 _( "<npcname> is shocked!" ) );
1472 u.mod_pain( total_damage / 2 );
1473 } else {
1474 u.add_msg_player_or_npc( m_bad, _( "You're shocked!" ), _( "<npcname> is shocked!" ) );
1475 }
1476 } else {
1477 u.add_msg_player_or_npc( _( "The electric cloud doesn't affect you." ),
1478 _( "The electric cloud doesn't seem to affect <npcname>." ) );
1479 }
1480 }
1481 }
1482 if( ft == fd_fatigue ) {
1483 // Assume the rift is on the ground for now to prevent issues with the player being unable access vehicle controls on the same tile due to teleportation.
1484 if( !u.in_vehicle ) {
1485 // Teleports you... somewhere.
1486 if( rng( 0, 2 ) < cur.get_field_intensity() && u.is_player() ) {
1487 add_msg( m_bad, _( "You're violently teleported!" ) );
1488 u.hurtall( cur.get_field_intensity(), nullptr );
1489 teleport::teleport( u );
1490 }
1491 }
1492 }
1493 // Why do these get removed???
1494 // Stepping on a shock vent shuts it down.
1495 if( ft == fd_shock_vent || ft == fd_acid_vent ) {
1496 cur.set_field_intensity( 0 );
1497 }
1498 if( ft == fd_bees ) {
1499 // Player is immune to bees while underwater.
1500 if( !u.is_underwater() ) {
1501 const int intensity = cur.get_field_intensity();
1502 // Bees will try to sting you in random body parts, up to 8 times.
1503 for( int i = 0; i < rng( 1, 7 ); i++ ) {
1505 int sum_cover = 0;
1506 for( const item &i : u.worn ) {
1507 if( i.covers( bp->token ) ) {
1508 sum_cover += i.get_coverage();
1509 }
1510 }
1511 // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part]
1512 // AND clothing on affected body part has low environmental protection value
1513 if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) &&
1514 u.add_env_effect( effect_stung, bp->token, intensity, 9_minutes ) ) {
1515 u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ),
1516 body_part_name_accusative( bp->token ) );
1517 }
1518 }
1519 }
1520 }
1521 if( ft == fd_incendiary ) {
1522 // Mysterious incendiary substance melts you horribly.
1523 if( u.has_trait( trait_M_SKIN2 ) ||
1524 u.has_trait( trait_M_SKIN3 ) ||
1525 cur.get_field_intensity() == 1 ) {
1526 u.add_msg_player_or_npc( m_bad, _( "The incendiary burns you!" ),
1527 _( "The incendiary burns <npcname>!" ) );
1528 u.hurtall( rng( 1, 3 ), nullptr );
1529 } else {
1530 u.add_msg_player_or_npc( m_bad, _( "The incendiary melts into your skin!" ),
1531 _( "The incendiary melts into <npcname>s skin!" ) );
1532 u.add_effect( effect_onfire, 8_turns, bp_torso );
1533 u.hurtall( rng( 2, 6 ), nullptr );
1534 }
1535 }
1536 // Both gases are unhealthy and become deadly if you cross a related threshold.
1537 if( ft == fd_fungicidal_gas || ft == fd_insecticidal_gas ) {
1538 // The gas won't harm you inside a vehicle.
1539 if( !inside ) {
1540 // Full body suits protect you from the effects of the gas.
1541 if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
1542 u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
1543 const int intensity = cur.get_field_intensity();
1544 bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes );
1546 ( ft == fd_insecticidal_gas && ( u.get_highest_category() == "INSECT" ||
1547 u.get_highest_category() == "SPIDER" ) ) ) {
1548 inhaled |= u.add_env_effect( effect_badpoison, bp_mouth, 5, intensity * 1_minutes );
1549 u.hurtall( rng( intensity, intensity * 2 ), nullptr );
1550 u.add_msg_if_player( m_bad, _( "The %s burns your skin." ), cur.name() );
1551 }
1552
1553 if( inhaled ) {
1554 u.add_msg_if_player( m_bad, _( "The %s makes you feel sick." ), cur.name() );
1555 }
1556 }
1557 }
1558 }
1559 }
1560}
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:331
@ bp_foot_l
Definition: bodypart.h:50
@ bp_leg_r
Definition: bodypart.h:49
@ bp_eyes
Definition: bodypart.h:42
@ bp_hand_l
Definition: bodypart.h:46
@ bp_arm_l
Definition: bodypart.h:44
@ bp_leg_l
Definition: bodypart.h:48
@ bp_hand_r
Definition: bodypart.h:47
@ bp_head
Definition: bodypart.h:41
@ bp_torso
Definition: bodypart.h:40
@ bp_mouth
Definition: bodypart.h:43
@ bp_foot_r
Definition: bodypart.h:51
@ bp_arm_r
Definition: bodypart.h:45
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: character.cpp:755
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6104
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3246
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:888
std::list< item > worn
Definition: character.h:1542
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:7005
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1206
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6848
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7815
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3216
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8635
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1507
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6461
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1810
bodypart_id get_random_body_part(bool main=false) const
Definition: creature.cpp:1641
virtual bool is_underwater() const
Definition: creature.cpp:171
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1648
int extra_radiation_min() const
Definition: field.cpp:14
int radiation_hurt_damage_min() const
Definition: field.cpp:24
std::string radiation_hurt_message() const
Definition: field.cpp:34
int extra_radiation_max() const
Definition: field.cpp:19
std::string name() const
Definition: field.h:84
int radiation_hurt_damage_max() const
Definition: field.cpp:29
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5900
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:743
int burn_body_part(player &u, field_entry &cur, body_part bp, int scale)
Definition: map_field.cpp:124
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:364
bool is_player() const override
Definition: player.h:93
field_type_id fd_bees
Definition: field_type.cpp:371
static const trait_id trait_M_SKIN3("M_SKIN3")
static const std::string flag_GAS_PROOF("GAS_PROOF")
static const efftype_id effect_fungus("fungus")
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const trait_id trait_THRESH_MARLOSS("THRESH_MARLOSS")
static const trait_id trait_WEB_WALKER("WEB_WALKER")
static const efftype_id effect_badpoison("badpoison")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const efftype_id effect_stung("stung")
static const efftype_id effect_poison("poison")
static const efftype_id effect_teargas("teargas")
static const bionic_id bio_heatsink("bio_heatsink")
hp_part
Definition: pldata.h:32
@ num_hp_parts
Definition: pldata.h:39
int type_damage(damage_type dt) const
Definition: damage.cpp:172
#define translate_marker(x)
Marks a string literal to be extracted for translation.
Definition: translations.h:30

References _, Creature::add_effect(), Creature::add_env_effect(), add_msg(), player::add_msg_if_player(), player::add_msg_player_or_npc(), bio_heatsink, body_part_name_accusative(), bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, burn_body_part(), Creature::check_dead_state(), convert_bp(), item::covers(), Character::deal_damage(), DT_ELECTRIC, DT_HEAT, effect_badpoison, effect_blind, effect_fungus, effect_onfire, effect_poison, effect_stung, effect_teargas, effect_webbed, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_sap, fd_shock_vent, fd_sludge, fd_tear_gas, fd_web, flag_GAS_PROOF(), Creature::get_all_body_parts(), Character::get_armor_cut(), item::get_coverage(), Character::get_env_resist(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), Character::get_highest_category(), Creature::get_random_body_part(), Character::has_active_bionic(), Character::has_trait(), Character::has_two_arms(), Character::hp_to_bp(), Character::hurtall(), string_id< T >::id(), Character::in_vehicle, Character::irradiate(), Character::is_elec_immune(), field_entry::is_field_alive(), Character::is_on_ground(), player::is_player(), Creature::is_underwater(), Character::is_wearing(), itype_rm13_armor_on, m_bad, m_warning, Character::mod_pain(), Creature::moves, field_entry::name(), num_bp, num_hp_parts, one_in(), Character::pos(), field_entry::radiation_hurt_damage_max(), field_entry::radiation_hurt_damage_min(), field_entry::radiation_hurt_message(), rng(), field_entry::set_field_intensity(), teleport::teleport(), dealt_damage_instance::total_damage(), trait_ACIDPROOF, trait_ELECTRORECEPTORS, trait_M_IMMUNE, trait_M_SKIN2, trait_M_SKIN3, trait_THRESH_MARLOSS, trait_THRESH_MYCUS, trait_WEB_WALKER, translate_marker, dealt_damage_instance::type_damage(), veh_at(), Character::worn, Character::worn_with_flag(), and x_in_y().

Referenced by creature_in_field().

◆ point_within_camp()

bool map::point_within_camp ( const tripoint point_check) const

Definition at line 5663 of file map.cpp.

5664{
5665 // TODO: fix point types
5666 const tripoint_abs_omt omt_check( ms_to_omt_copy( point_check ) );
5667 const point_abs_omt p = omt_check.xy();
5668 for( int x2 = -2; x2 < 2; x2++ ) {
5669 for( int y2 = -2; y2 < 2; y2++ ) {
5670 if( std::optional<basecamp *> bcp = overmap_buffer.find_camp( p + point( x2, y2 ) ) ) {
5671 return ( *bcp )->camp_omt_pos().z() == point_check.z;
5672 }
5673 }
5674 }
5675 return false;
5676}
constexpr auto xy() const
Definition: coordinates.h:130
std::optional< basecamp * > find_camp(const point_abs_omt &p)

References overmapbuffer::find_camp(), ms_to_omt_copy(), overmap_buffer, coords::coord_point< Point, Origin, Scale >::xy(), and tripoint::z.

Referenced by npc::worker_downtime().

◆ points_in_radius()

tripoint_range< tripoint > map::points_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
) const

Definition at line 8732 of file map.cpp.

8734{
8735 const tripoint min( std::max<int>( 0, center.x - radius ), std::max<int>( 0, center.y - radius ),
8736 clamp<int>( center.z - radiusz, -OVERMAP_DEPTH, OVERMAP_HEIGHT ) );
8737 const tripoint max( std::min<int>( SEEX * my_MAPSIZE - 1, center.x + radius ),
8738 std::min<int>( SEEX * my_MAPSIZE - 1, center.y + radius ), clamp<int>( center.z + radiusz,
8740 return tripoint_range<tripoint>( min, max );
8741}

References center, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, and SEEX.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), Character::activate_bionic(), add_splash(), npc::alt_attack(), apply_ammo_effects(), are_requirements_nearby(), npc::assess_danger(), bash_furn_success(), Character::blossoms(), activity_handlers::butcher_finish(), leap_actor::call(), can_do_activity_there(), iexamine::cardreader(), iexamine::cardreader_foodplace(), deploy_tent_actor::check_intact(), choose_adjacent_highlight(), activity_handlers::chop_tree_finish(), climb_difficulty(), collapse_at(), collapse_check(), complete_construction(), consider_butchery(), game::control_vehicle(), displace_water(), enumerate_objects_around_point(), Character::env_surgery_bonus(), ranged::execute_shaped_attack(), ranged::expected_coverage(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), computer_session::failure_manhacks(), computer_session::failure_secubots(), computer_session::failure_shutdown(), find_empty_spot_nearby(), find_furnitures_or_vparts_with_flag_in_radius(), find_furnitures_with_flag_in_radius(), find_potential_computer_point(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), generic_multi_activity_check_requirement(), generic_multi_activity_locations(), get_creatures_in_radius(), get_heat_radiation(), liquid_handler::get_liquid_target(), zone_manager::get_point_set_loot(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), npc::go_to_omt_destination(), handle_action_menu(), has_adjacent_furniture_with(), has_nearby_chair(), has_nearby_fire(), has_nearby_table(), has_neighbor(), is_cornerfloor(), is_wall_adjacent(), map_funcs::migo_nerve_cage_removal(), game::monmove(), npc::move_away_from(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), iexamine::nanofab(), iuse::note_bionics(), trap::on_disarmed(), operator_present(), tutorial_game::per_turn(), photo_def_for_camera_point(), character_funcs::pick_safe_adjacent_tile(), place_construction(), game::place_critter_around(), mission_start::place_deposit_box(), game::place_player(), place_vending(), iexamine::portable_structure(), tutorial_game::post_action(), game::process_artifact(), process_fields_in_submap(), relic_funcs::process_recharge_entry(), propagate_suspension_check(), avatar_action::ramp_move(), reachable_flood_steps(), editmap::recalc_target(), requirements_map(), mattack::riotbot(), route_adjacent(), character_funcs::search_surroundings(), mattack::shriek_stun(), spawn_monsters_submap(), mdeath::splatter(), Character::spores(), fungal_effects::spread_fungus(), spread_gas(), monster::stumble(), activity_handlers::travel_do_turn(), explosion_iuse::trigger_explosion(), try_remove_grab(), turnOnSelectedPump(), place_trap_actor::use(), deploy_tent_actor::use(), use_amount(), game::vertical_move(), and npc::worker_downtime().

◆ points_in_rectangle()

tripoint_range< tripoint > map::points_in_rectangle ( const tripoint from,
const tripoint to 
) const

Definition at line 8722 of file map.cpp.

8723{
8724 const tripoint min( std::max( 0, std::min( from.x, to.x ) ), std::max( 0, std::min( from.y,
8725 to.y ) ), std::max( -OVERMAP_DEPTH, std::min( from.z, to.z ) ) );
8726 const tripoint max( std::min( SEEX * my_MAPSIZE - 1, std::max( from.x, to.x ) ),
8727 std::min( SEEX * my_MAPSIZE - 1, std::max( from.y, to.y ) ), std::min( OVERMAP_HEIGHT,
8728 std::max( from.z, to.z ) ) );
8729 return tripoint_range<tripoint>( min, max );
8730}

References my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_camp_ownership(), apply_faction_ownership(), debug_menu::debug(), draw_lab(), draw_mine(), farm_action(), game::find_or_make_stairs(), generate_lightmap(), jmapgen_setmap::has_vehicle_collision(), avatar_action::move(), MapExtras::mx_portal(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), and om_harvest_ter().

◆ points_on_zlevel() [1/2]

tripoint_range< tripoint > map::points_on_zlevel ( ) const

◆ points_on_zlevel() [2/2]

tripoint_range< tripoint > map::points_on_zlevel ( int  z) const

Same as above, but uses the specific z-level.

If the given z-level is invalid, it returns an empty range.

Definition at line 8743 of file map.cpp.

8744{
8745 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
8746 // TODO: need a default constructor that creates an empty range.
8748 }
8750 tripoint( 0, 0, z ), tripoint( SEEX * my_MAPSIZE - 1, SEEY * my_MAPSIZE - 1, z ) );
8751}

References my_MAPSIZE, OVERMAP_HEIGHT, SEEX, SEEY, tripoint_above, and tripoint_zero.

◆ process_falling()

void map::process_falling ( )

Invoked drop_everything on cached dirty tiles.

Definition at line 2355 of file map.cpp.

2356{
2357 if( !zlevels ) {
2358 support_cache_dirty.clear();
2359 return;
2360 }
2361
2362 if( !support_cache_dirty.empty() ) {
2363 add_msg( m_debug, "Checking %d tiles for falling objects",
2364 support_cache_dirty.size() );
2365 // We want the cache to stay constant, but falling can change it
2366 std::set<tripoint> last_cache = std::move( support_cache_dirty );
2367 support_cache_dirty.clear();
2368 for( const tripoint &p : last_cache ) {
2369 drop_everything( p );
2370 }
2371 }
2372}
void drop_everything(const tripoint &p)
Handles map objects of given type (not creatures) falling down.
Definition: map.cpp:2126
std::set< tripoint > support_cache_dirty
Definition: map.h:1494

References add_msg(), drop_everything(), m_debug, avatar_action::move(), support_cache_dirty, and zlevels.

Referenced by game::do_turn().

◆ process_fields()

void map::process_fields ( )

Definition at line 141 of file map_field.cpp.

142{
143 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
144 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
145 for( int z = minz; z <= maxz; z++ ) {
146 auto &field_cache = get_cache( z ).field_cache;
147 for( int x = 0; x < my_MAPSIZE; x++ ) {
148 for( int y = 0; y < my_MAPSIZE; y++ ) {
149 if( field_cache[ x + y * MAPSIZE ] ) {
150 submap *const current_submap = get_submap_at_grid( { x, y, z } );
151 process_fields_in_submap( current_submap, tripoint( x, y, z ) );
152 }
153 }
154 }
155
156 // no need to invalidate "transparency" and "seen" caches here
157 // they are invalidated point by point inside the `process_fields_in_submap`
158 }
159}
void process_fields_in_submap(submap *current_submap, const tripoint &submap_pos)
Definition: map_field.cpp:396

References abs_sub, level_cache::field_cache, get_cache(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, process_fields_in_submap(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_fields_in_submap()

void map::process_fields_in_submap ( submap current_submap,
const tripoint submap_pos 
)

Definition at line 396 of file map_field.cpp.

398{
399 scent_block sblk( submap, g->scent );
400
401 // Holds m.field_at(x,y).find_field(fd_some_field) type returns.
402 // Just to avoid typing that long string for a temp value.
403 field_entry *tmpfld = nullptr;
404
405 map &here = get_map();
406 tripoint thep;
407 thep.z = submap.z;
408
409 // Initialize the map tile wrapper
410 maptile map_tile( current_submap, point_zero );
411 int &locx = map_tile.pos_.x;
412 int &locy = map_tile.pos_.y;
413 const point sm_offset( submap.x * SEEX, submap.y * SEEY );
414
415 // Loop through all tiles in this submap indicated by current_submap
416 for( locx = 0; locx < SEEX; locx++ ) {
417 for( locy = 0; locy < SEEY; locy++ ) {
418 // Get a reference to the field variable from the submap;
419 // contains all the pointers to the real field effects.
420 field &curfield = current_submap->get_field( { static_cast<int>( locx ), static_cast<int>( locy ) } );
421
422 // when displayed_field_type == fd_null it means that `curfield` has no fields inside
423 // avoids instantiating (relatively) expensive map iterator
424 if( !curfield.displayed_field_type() ) {
425 continue;
426 }
427
428 // This is a translation from local coordinates to submap coordinates.
429 // All submaps are in one long 1d array.
430 thep.x = locx + sm_offset.x;
431 thep.y = locy + sm_offset.y;
432 // A const reference to the tripoint above, so that the code below doesn't accidentally change it
433 const tripoint &p = thep;
434
435 // This should be true only when the field in the current tile changes transparency state,
436 // More correctly: not just when the field is opaque, but when it changes state
437 // to a more/less transparent one
438 bool dirty_transparency_cache = false;
439
440 for( auto it = curfield.begin(); it != curfield.end(); ) {
441 // Iterating through all field effects in the submap's field.
442 field_entry &cur = it->second;
443
444 // Holds cur.get_field_type() as that is what the old system used before rewrite.
445 field_type_id cur_fd_type_id = cur.get_field_type();
446
447 // The field might have been killed by processing a neighbor field
448 if( !cur.is_field_alive() ) {
449 if( !cur_fd_type_id->get_transparent( cur.get_field_intensity() - 1 ) ) {
450 dirty_transparency_cache = true;
451 }
452 --current_submap->field_count;
453 curfield.remove_field( it++ );
454 continue;
455 }
456
457 // Again, legacy support in the event someone Mods set_field_intensity to allow more values.
458 if( cur.get_field_intensity() > 3 || cur.get_field_intensity() < 1 ) {
459 // TODO: Remove this eventually as we would suppoort more than 3 field intensity levels
460 debugmsg( "Whoooooa intensity of %d", cur.get_field_intensity() );
461 }
462
463 dirty_transparency_cache |= cur_fd_type_id->dirty_transparency_cache;
464
465 // Don't process "newborn" fields. This gives the player time to run if they need to.
466 if( cur.get_field_age() == 0_turns ) {
467 cur_fd_type_id = fd_null;
468 }
469
470 const field_type &cur_fd_type = *cur_fd_type_id;
471
472 // Upgrade field intensity
473 if( cur.intensity_upgrade_chance() > 0 &&
475 cur.intensity_upgrade_duration() > 0_turns &&
478 }
479
480 int part;
481 const ter_t &ter = map_tile.get_ter_t();
482 // Dissipate faster in water
483 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
485 }
486 if( cur_fd_type_id == fd_acid ) {
487 // Try to fall by a z-level
488 if( zlevels && p.z > -OVERMAP_DEPTH ) {
489 tripoint dst{ p.xy(), p.z - 1 };
490 if( valid_move( p, dst, true, true ) ) {
491 field_entry *acid_there = field_at( dst ).find_field( fd_acid );
492 if( acid_there == nullptr ) {
494 } else {
495 // Math can be a bit off,
496 // but "boiling" falling acid can be allowed to be stronger
497 // than acid that just lies there
498 const int sum_intensity = cur.get_field_intensity() + acid_there->get_field_intensity();
499 const int new_intensity = std::min( 3, sum_intensity );
500 // No way to get precise elapsed time, let's always reset
501 // Allow falling acid to last longer than regular acid to show it off
502 const time_duration new_age = -1_minutes * ( sum_intensity - new_intensity );
503 acid_there->set_field_intensity( new_intensity );
504 acid_there->set_field_age( new_age );
505 }
506
507 // Set ourselves up for removal
508 cur.set_field_intensity( 0 );
509 }
510 }
511 // TODO: Allow spreading to the sides if age < 0 && intensity == 3
512 }
513 if( cur_fd_type.apply_slime_factor > 0 ) {
514 sblk.apply_slime( p, cur.get_field_intensity() * cur_fd_type.apply_slime_factor );
515 }
516 if( cur_fd_type_id == fd_fire ) {
517 cur.set_field_age( std::max( -24_hours, cur.get_field_age() ) );
518 // Entire objects for ter/frn for flags
519 const ter_t &ter = map_tile.get_ter_t();
520 const furn_t &frn = map_tile.get_furn_t();
521
522 // We've got ter/furn cached, so let's use that
523 const bool is_sealed = ter_furn_has_flag( ter, frn, TFLAG_SEALED ) &&
525 // Consumed items count
526 int consumed = 0;
527 // How much time to add to the fire's life due to burned items/terrain/furniture
528 time_duration time_added = 0_turns;
529 // Checks if the fire can spread
530 const bool can_spread = !ter_furn_has_flag( ter, frn, TFLAG_FIRE_CONTAINER );
531 const bool no_floor = ter.has_flag( TFLAG_NO_FLOOR );
532 // If the flames are in furniture with fire_container flag like brazier or oven,
533 // they're fully contained, so skip consuming terrain
534 const bool can_burn = !no_floor && can_spread &&
535 ( check_flammable( ter ) || check_flammable( frn ) );
536 // The huge indent below should probably be somehow moved away from here
537 // without forcing the function to use i_at( p ) for fires without items
538 if( !is_sealed && map_tile.get_item_count() > 0 ) {
539 map_stack items_here = i_at( p );
540 std::vector<item> new_content;
541 for( auto explosive = items_here.begin(); explosive != items_here.end(); ) {
542 if( explosive->will_explode_in_fire() ) {
543 // We need to make a copy because the iterator validity is not predictable
544 item copy = *explosive;
545 explosive = items_here.erase( explosive );
546 if( copy.detonate( p, new_content ) ) {
547 // Need to restart, iterators may not be valid
548 explosive = items_here.begin();
549 }
550 } else {
551 ++explosive;
552 }
553 }
554
555 fire_data frd( cur.get_field_intensity(), !can_spread );
556 // The highest # of items this fire can remove in one turn
557 int max_consume = cur.get_field_intensity() * 2;
558
559 for( auto fuel = items_here.begin(); fuel != items_here.end() && consumed < max_consume; ) {
560 // `item::burn` modifies the charges in order to simulate some of them getting
561 // destroyed by the fire, this changes the item weight, but may not actually
562 // destroy it. We need to spawn products anyway.
563 const units::mass old_weight = fuel->weight( false );
564 bool destroyed = fuel->burn( frd );
565 // If the item is considered destroyed, it may have negative charge count,
566 // see `item::burn?. This in turn means `item::weight` returns a negative value,
567 // which we can not use, so only call `weight` when it's still an existing item.
568 const units::mass new_weight = destroyed ? 0_gram : fuel->weight( false );
569 if( old_weight != new_weight ) {
570 create_burnproducts( p, *fuel, old_weight - new_weight );
571 }
572
573 if( destroyed ) {
574 // If we decided the item was destroyed by fire, remove it.
575 // But remember its contents, except for irremovable mods, if any
576 const std::list<item *> content_list = fuel->contents.all_items_top();
577 for( item *it : content_list ) {
578 if( !it->is_irremovable() ) {
579 new_content.push_back( item( *it ) );
580 }
581 }
582 fuel = items_here.erase( fuel );
583 consumed++;
584 } else {
585 ++fuel;
586 }
587 }
588
589 spawn_items( p, new_content );
590 time_added = 1_turns * roll_remainder( frd.fuel_produced );
591 }
592
593 // Get the part of the vehicle in the fire (_internal skips the boundary check)
594 vehicle *veh = veh_at_internal( p, part );
595 if( veh != nullptr ) {
596 veh->damage( part, cur.get_field_intensity() * 10, DT_HEAT, true );
597 // Damage the vehicle in the fire.
598 }
599 if( can_burn ) {
600 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
601 // Flames die quickly on water
602 cur.set_field_age( cur.get_field_age() + 4_minutes );
603 }
604
605 // Consume the terrain we're on
606 if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE ) ) {
607 // The fire feeds on the ground itself until max intensity.
608 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
609 if( cur.get_field_intensity() > 1 &&
610 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
611 destroy( p, false );
612 }
613
614 } else if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE_HARD ) &&
615 one_in( 3 ) ) {
616 // The fire feeds on the ground itself until max intensity.
617 time_added += 1_turns * ( 4 - cur.get_field_intensity() );
618 if( cur.get_field_intensity() > 1 &&
619 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
620 destroy( p, false );
621 }
622
623 } else if( ter.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
624 // The fire feeds on the ground itself until max intensity.
625 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
626 if( cur.get_field_intensity() > 1 &&
627 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
628 if( p.z > 0 ) {
629 // We're in the air
630 ter_set( p, t_open_air );
631 } else {
632 ter_set( p, t_dirt );
633 }
634 }
635
636 } else if( frn.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
637 // The fire feeds on the ground itself until max intensity.
638 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
639 if( cur.get_field_intensity() > 1 &&
640 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
641 furn_set( p, f_ash );
642 }
643
644 }
645 }
646
647 if( ter.has_flag( TFLAG_NO_FLOOR ) && zlevels && p.z > -OVERMAP_DEPTH ) {
648 // We're hanging in the air - let's fall down
649 tripoint dst{ p.xy(), p.z - 1 };
650 if( valid_move( p, dst, true, true ) ) {
651 maptile dst_tile = maptile_at_internal( dst );
652 field_entry *fire_there = dst_tile.find_field( fd_fire );
653 if( fire_there == nullptr ) {
654 add_field( dst, fd_fire, 1, 0_turns, false );
656 } else {
657 // Don't fuel raging fires or they'll burn forever
658 // as they can produce small fires above themselves
659 int new_intensity = std::max( cur.get_field_intensity(),
660 fire_there->get_field_intensity() );
661 // Allow smaller fires to combine
662 if( new_intensity < 3 &&
663 cur.get_field_intensity() == fire_there->get_field_intensity() ) {
664 new_intensity++;
665 }
666 // A raging fire below us can support us for a while
667 // Otherwise decay and decay fast
668 if( fire_there->get_field_intensity() < 3 || one_in( 10 ) ) {
670 }
671 fire_there->set_field_intensity( new_intensity );
672 }
673 break;
674 }
675 }
676 // Lower age is a longer lasting fire
677 if( time_added != 0_turns ) {
678 cur.set_field_age( cur.get_field_age() - time_added );
679 } else if( can_burn ) {
680 // Nothing to burn = fire should be dying out faster
681 // Drain more power from big fires, so that they stop raging over nothing
682 // Except for fires on stoves and fireplaces, those are made to keep the fire alive
683 cur.mod_field_age( 10_seconds * cur.get_field_intensity() );
684 }
685
686 // Allow raging fires (and only raging fires) to spread up
687 // Spreading down is achieved by wrecking the walls/floor and then falling
688 if( zlevels && cur.get_field_intensity() == 3 && p.z < OVERMAP_HEIGHT ) {
689 const tripoint dst_p = tripoint( p.xy(), p.z + 1 );
690 // Let it burn through the floor
691 maptile dst = maptile_at_internal( dst_p );
692 const auto &dst_ter = dst.get_ter_t();
693 if( dst_ter.has_flag( TFLAG_NO_FLOOR ) ||
694 dst_ter.has_flag( TFLAG_FLAMMABLE ) ||
695 dst_ter.has_flag( TFLAG_FLAMMABLE_ASH ) ||
696 dst_ter.has_flag( TFLAG_FLAMMABLE_HARD ) ) {
697 field_entry *nearfire = dst.find_field( fd_fire );
698 if( nearfire != nullptr ) {
699 nearfire->mod_field_age( -2_turns );
700 } else {
701 add_field( dst_p, fd_fire, 1, 0_turns, false );
702 }
703 // Fueling fires above doesn't cost fuel
704 }
705 }
706
707 // Below we will access our nearest 8 neighbors, so let's cache them now
708 // This should probably be done more globally, because large fires will re-do it a lot
709 auto neighs = get_neighbors( p );
710
711 // If the flames are in a pit, it can't spread to non-pit
712 const bool in_pit = can_spread && ter.id.id() == t_pit;
713
714 // Count adjacent fires, to optimize out needless smoke and hot air
715 int adjacent_fires = 0;
716
717 // If the flames are big, they contribute to adjacent flames
718 if( can_spread ) {
719 if( cur.get_field_intensity() > 1 && one_in( 3 ) ) {
720 // Basically: Scan around for a spot,
721 // if there is more fire there, make it bigger and give it some fuel.
722 // This is how big fires spend their excess age:
723 // making other fires bigger. Flashpoint.
724 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
725 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
726 count != neighs.size() && cur.get_field_age() < 0_turns;
727 i = ( i + 1 ) % neighs.size(), count++ ) {
728 maptile &dst = neighs[i].second;
729 auto dstfld = dst.find_field( fd_fire );
730 // If the fire exists and is weaker than ours, boost it
731 if( dstfld != nullptr &&
732 ( dstfld->get_field_intensity() <= cur.get_field_intensity() ||
733 dstfld->get_field_age() > cur.get_field_age() ) &&
734 ( in_pit == ( dst.get_ter() == t_pit ) ) ) {
735 if( dstfld->get_field_intensity() < 2 ) {
736 dstfld->set_field_intensity( dstfld->get_field_intensity() + 1 );
737 }
738
739 dstfld->set_field_age( dstfld->get_field_age() - 5_minutes );
740 cur.set_field_age( cur.get_field_age() + 5_minutes );
741 }
742 if( dstfld != nullptr ) {
743 adjacent_fires++;
744 }
745 }
746 } else if( cur.get_field_age() < 0_turns && cur.get_field_intensity() < 3 ) {
747 // See if we can grow into a stage 2/3 fire, for this
748 // burning neighbors are necessary in addition to
749 // field age < 0, or alternatively, a LOT of fuel.
750
751 // The maximum fire intensity is 1 for a lone fire, 2 for at least 1 neighbor,
752 // 3 for at least 2 neighbors.
753 int maximum_intensity = 1;
754
755 // The following logic looks a bit complex due to optimization concerns, so here are the semantics:
756 // 1. Calculate maximum field intensity based on fuel, -50 minutes is 2(medium), -500 minutes is 3(raging)
757 // 2. Calculate maximum field intensity based on neighbors, 3 neighbors is 2(medium), 7 or more neighbors is 3(raging)
758 // 3. Pick the higher maximum between 1. and 2.
759 if( cur.get_field_age() < -500_minutes ) {
760 maximum_intensity = 3;
761 } else {
762 for( auto &neigh : neighs ) {
763 if( neigh.second.get_field().find_field( fd_fire ) != nullptr ) {
764 adjacent_fires++;
765 }
766 }
767 maximum_intensity = 1 + ( adjacent_fires >= 3 ) + ( adjacent_fires >= 7 );
768
769 if( maximum_intensity < 2 && cur.get_field_age() < -50_minutes ) {
770 maximum_intensity = 2;
771 }
772 }
773
774 // If we consumed a lot, the flames grow higher
775 if( cur.get_field_intensity() < maximum_intensity && cur.get_field_age() < 0_turns ) {
776 // Fires under 0 age grow in size. Level 3 fires under 0 spread later on.
777 // Weaken the newly-grown fire
779 cur.set_field_age( cur.get_field_age() + 10_minutes * cur.get_field_intensity() );
780 }
781 }
782
783 // Consume adjacent fuel / terrain / webs to spread.
784 // Our iterator will start at end_i + 1 and increment from there and then wrap around.
785 // This guarantees it will check all neighbors, starting from a random one
786 const size_t end_i = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
787 for( size_t i = ( end_i + 1 ) % neighs.size(), count = 0;
788 count != neighs.size();
789 i = ( i + 1 ) % neighs.size(), count++ ) {
790 if( one_in( cur.get_field_intensity() * 2 ) ) {
791 // Skip some processing to save on CPU
792 continue;
793 }
794
795 tripoint &dst_p = neighs[i].first;
796 maptile &dst = neighs[i].second;
797 // No bounds checking here: we'll treat the invalid neighbors as valid.
798 // We're using the map tile wrapper, so we can treat invalid tiles as sentinels.
799 // This will create small oddities on map edges, but nothing more noticeable than
800 // "cut-off" that happens with bounds checks.
801
802 field_entry *nearfire = dst.find_field( fd_fire );
803 if( nearfire != nullptr ) {
804 // We handled supporting fires in the section above, no need to do it here
805 continue;
806 }
807
808 field_entry *nearwebfld = dst.find_field( fd_web );
809 int spread_chance = 25 * ( cur.get_field_intensity() - 1 );
810 if( nearwebfld != nullptr ) {
811 spread_chance = 50 + spread_chance / 2;
812 }
813
814 const ter_t &dster = dst.get_ter_t();
815 const furn_t &dsfrn = dst.get_furn_t();
816 // Allow weaker fires to spread occasionally
817 const int power = cur.get_field_intensity() + one_in( 5 );
818 if( can_spread && rng( 1, 100 ) < spread_chance &&
819 ( check_flammable( dster ) || check_flammable( dsfrn ) ) &&
820 ( in_pit == ( dster.id.id() == t_pit ) ) &&
821 (
822 ( power >= 3 && cur.get_field_age() < 0_turns && one_in( 20 ) ) ||
823 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) ||
824 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_ASH ) && one_in( 2 ) ) ) ||
825 ( power >= 3 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_HARD ) && one_in( 5 ) ) ) ||
826 nearwebfld || ( dst.get_item_count() > 0 &&
828 one_in( 5 ) )
829 ) ) {
830 // Nearby open flammable ground? Set it on fire.
831 add_field( dst_p, fd_fire, 1, 0_turns, false );
832 tmpfld = dst.find_field( fd_fire );
833 if( tmpfld != nullptr ) {
834 // Make the new fire quite weak, so that it doesn't start jumping around instantly
835 tmpfld->set_field_age( 2_minutes );
836 // Consume a bit of our fuel
837 cur.set_field_age( cur.get_field_age() + 1_minutes );
838 }
839 if( nearwebfld ) {
840 nearwebfld->set_field_intensity( 0 );
841 }
842 }
843 }
844 }
845 }
846
847 // Spread gaseous fields
848 if( cur.gas_can_spread() ) {
849 const int gas_percent_spread = cur_fd_type.percent_spread;
850 if( gas_percent_spread > 0 ) {
851 const time_duration outdoor_age_speedup = cur_fd_type.outdoor_age_speedup;
852 spread_gas( cur, p, gas_percent_spread, outdoor_age_speedup, sblk );
853 }
854 }
855
856 if( cur_fd_type_id == fd_fungal_haze ) {
857 if( one_in( 10 - 2 * cur.get_field_intensity() ) ) {
858 // Haze'd terrain
859 fungal_effects( *g, here ).spread_fungus( p );
860 }
861 }
862
863 // Process npc complaints
864 const std::tuple<int, std::string, time_duration, std::string> &npc_complain_data =
865 cur_fd_type.npc_complain_data;
866 const int chance = std::get<0>( npc_complain_data );
867 if( chance > 0 && one_in( chance ) ) {
868 if( npc *const np = g->critter_at<npc>( p, false ) ) {
869 np->complain_about( std::get<1>( npc_complain_data ),
870 std::get<2>( npc_complain_data ),
871 std::get<3>( npc_complain_data ) );
872 }
873 }
874
875 // Apply radiation
876 if( cur.extra_radiation_max() > 0 ) {
877 int extra_radiation = rng( cur.extra_radiation_min(), cur.extra_radiation_max() );
878 adjust_radiation( p, extra_radiation );
879 }
880
881 // Apply wandering fields from vents
882 if( cur_fd_type.wandering_field ) {
883 for( const tripoint &pnt : points_in_radius( p, cur.get_field_intensity() - 1 ) ) {
884 field &wandering_field = get_field( pnt );
885 tmpfld = wandering_field.find_field( cur_fd_type.wandering_field );
886 if( tmpfld && tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
887 tmpfld->set_field_intensity( tmpfld->get_field_intensity() + 1 );
888 } else {
889 add_field( pnt, cur_fd_type.wandering_field, cur.get_field_intensity() );
890 }
891 }
892 }
893
894 if( cur_fd_type_id == fd_fire_vent ) {
895
896 if( cur.get_field_intensity() > 1 ) {
897 if( one_in( 3 ) ) {
899 }
901 } else {
902 dirty_transparency_cache = true;
903 add_field( p, fd_flame_burst, 3, cur.get_field_age() );
904 cur.set_field_intensity( 0 );
905 }
906 }
907 if( cur_fd_type_id == fd_flame_burst ) {
908 if( cur.get_field_intensity() > 1 ) {
911 } else {
912 dirty_transparency_cache = true;
913 add_field( p, fd_fire_vent, 3, cur.get_field_age() );
914 cur.set_field_intensity( 0 );
915 }
916 }
917 if( cur_fd_type_id == fd_electricity ) {
918 // 4 in 5 chance to spread
919 if( !one_in( 5 ) ) {
920 std::vector<tripoint> valid;
921 // We're grounded
922 if( impassable( p ) && cur.get_field_intensity() > 1 ) {
923 int tries = 0;
924 tripoint pnt;
925 pnt.z = p.z;
926 while( tries < 10 && cur.get_field_age() < 5_minutes && cur.get_field_intensity() > 1 ) {
927 pnt.x = p.x + rng( -1, 1 );
928 pnt.y = p.y + rng( -1, 1 );
929 if( passable( pnt ) && !obstructed_by_vehicle_rotation( p, pnt ) ) {
930 add_field( pnt, fd_electricity, 1, cur.get_field_age() + 1_turns );
932 tries = 0;
933 } else {
934 tries++;
935 }
936 }
937 // We're not grounded; attempt to ground
938 } else {
939 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
940 // Grounded tiles first
941 if( impassable( dst ) ) {
942 valid.push_back( dst );
943 }
944 }
945 // Spread to adjacent space, then
946 if( valid.empty() ) {
947 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
948 field_entry *elec = get_field( dst ).find_field( fd_electricity );
949 bool pass = passable( dst ) && !obstructed_by_vehicle_rotation( p, dst );
950 if( pass && elec != nullptr &&
951 elec->get_field_intensity() < 3 ) {
952 elec->set_field_intensity( elec->get_field_intensity() + 1 );
954 } else if( pass ) {
955 add_field( dst, fd_electricity, 1, cur.get_field_age() + 1_turns );
956 }
958 }
959 while( !valid.empty() && cur.get_field_intensity() > 1 ) {
960 const tripoint target = random_entry_removed( valid );
961 add_field( target, fd_electricity, 1, cur.get_field_age() + 1_turns );
963 }
964 }
965 }
966 }
967
968 int monster_spawn_chance = cur.monster_spawn_chance();
969 int monster_spawn_count = cur.monster_spawn_count();
970 if( monster_spawn_count > 0 && monster_spawn_chance > 0 && one_in( monster_spawn_chance ) ) {
971 for( ; monster_spawn_count > 0; monster_spawn_count-- ) {
973 cur.monster_spawn_group(), &monster_spawn_count );
974 if( !spawn_details.name ) {
975 continue;
976 }
977 if( const std::optional<tripoint> spawn_point = random_point(
979 [this]( const tripoint & n ) {
980 return passable( n );
981 } ) ) {
982 add_spawn( spawn_details.name, spawn_details.pack_size, *spawn_point );
983 }
984 }
985 }
986
987 if( cur_fd_type_id == fd_push_items ) {
988 map_stack items = i_at( p );
989 for( auto pushee = items.begin(); pushee != items.end(); ) {
990 if( pushee->typeId() != itype_rock ||
991 pushee->age() < 1_turns ) {
992 pushee++;
993 } else {
994 item tmp = *pushee;
995 tmp.set_age( 0_turns );
996 pushee = items.erase( pushee );
997 std::vector<tripoint> valid;
998 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
999 if( get_field( dst, fd_push_items ) != nullptr ) {
1000 valid.push_back( dst );
1001 }
1002 }
1003 if( !valid.empty() ) {
1004 tripoint newp = random_entry( valid );
1005 add_item_or_charges( newp, tmp );
1006 if( g->u.pos() == newp ) {
1007 add_msg( m_bad, _( "A %s hits you!" ), tmp.tname() );
1008 const bodypart_id hit = g->u.get_random_body_part();
1009 g->u.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1010 g->u.check_dead_state();
1011 }
1012
1013 if( npc *const p = g->critter_at<npc>( newp ) ) {
1014 // TODO: combine with player character code above
1015 const bodypart_id hit = g->u.get_random_body_part();
1016 p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1017 if( g->u.sees( newp ) ) {
1018 add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name );
1019 }
1020 p->check_dead_state();
1021 } else if( monster *const mon = g->critter_at<monster>( newp ) ) {
1022 mon->apply_damage( nullptr, bodypart_id( "torso" ),
1023 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) );
1024 if( g->u.sees( newp ) ) {
1025 add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() );
1026 }
1027 mon->check_dead_state();
1028 }
1029 }
1030 }
1031 }
1032 }
1033 if( cur_fd_type_id == fd_shock_vent ) {
1034 if( cur.get_field_intensity() > 1 ) {
1035 if( one_in( 5 ) ) {
1037 }
1038 } else {
1039 cur.set_field_intensity( 3 );
1040 int num_bolts = rng( 3, 6 );
1041 for( int i = 0; i < num_bolts; i++ ) {
1042 int xdir = 0;
1043 int ydir = 0;
1044 while( xdir == 0 && ydir == 0 ) {
1045 xdir = rng( -1, 1 );
1046 ydir = rng( -1, 1 );
1047 }
1048 int dist = rng( 4, 12 );
1049 int boltx = p.x;
1050 int bolty = p.y;
1051 for( int n = 0; n < dist; n++ ) {
1052 boltx += xdir;
1053 bolty += ydir;
1054 add_field( tripoint( boltx, bolty, p.z ), fd_electricity, rng( 2, 3 ) );
1055 if( one_in( 4 ) ) {
1056 if( xdir == 0 ) {
1057 xdir = rng( 0, 1 ) * 2 - 1;
1058 } else {
1059 xdir = 0;
1060 }
1061 }
1062 if( one_in( 4 ) ) {
1063 if( ydir == 0 ) {
1064 ydir = rng( 0, 1 ) * 2 - 1;
1065 } else {
1066 ydir = 0;
1067 }
1068 }
1069 }
1070 }
1071 }
1072 }
1073 if( cur_fd_type_id == fd_acid_vent ) {
1074
1075 if( cur.get_field_intensity() > 1 ) {
1076 if( cur.get_field_age() >= 1_minutes ) {
1078 cur.set_field_age( 0_turns );
1079 }
1080 } else {
1081 cur.set_field_intensity( 3 );
1082 for( const tripoint &t : points_in_radius( p, 5 ) ) {
1083 const field_entry *acid = get_field( t, fd_acid );
1084 if( acid != nullptr && acid->get_field_intensity() == 0 ) {
1085 int new_intensity = 3 - rl_dist( p, t ) / 2 + ( one_in( 3 ) ? 1 : 0 );
1086 if( new_intensity > 3 ) {
1087 new_intensity = 3;
1088 }
1089 if( new_intensity > 0 ) {
1090 add_field( t, fd_acid, new_intensity );
1091 }
1092 }
1093 }
1094 }
1095 }
1096 if( cur_fd_type_id == fd_bees ) {
1097 // Poor bees are vulnerable to so many other fields.
1098 // TODO: maybe adjust effects based on different fields.
1099 if( curfield.find_field( fd_web ) ||
1100 curfield.find_field( fd_fire ) ||
1101 curfield.find_field( fd_smoke ) ||
1102 curfield.find_field( fd_toxic_gas ) ||
1103 curfield.find_field( fd_tear_gas ) ||
1104 curfield.find_field( fd_relax_gas ) ||
1105 curfield.find_field( fd_nuke_gas ) ||
1106 curfield.find_field( fd_gas_vent ) ||
1107 curfield.find_field( fd_smoke_vent ) ||
1108 curfield.find_field( fd_fungicidal_gas ) ||
1109 curfield.find_field( fd_insecticidal_gas ) ||
1110 curfield.find_field( fd_fire_vent ) ||
1111 curfield.find_field( fd_flame_burst ) ||
1112 curfield.find_field( fd_electricity ) ||
1113 curfield.find_field( fd_fatigue ) ||
1114 curfield.find_field( fd_shock_vent ) ||
1115 curfield.find_field( fd_plasma ) ||
1116 curfield.find_field( fd_laser ) ||
1117 curfield.find_field( fd_dazzling ) ||
1118 curfield.find_field( fd_electricity ) ||
1119 curfield.find_field( fd_incendiary ) ) {
1120 // Kill them at the end of processing.
1121 cur.set_field_intensity( 0 );
1122 } else {
1123 // Bees chase the player if in range, wander randomly otherwise.
1124 if( !g->u.is_underwater() &&
1125 rl_dist( p, g->u.pos() ) < 10 &&
1126 clear_path( p, g->u.pos(), 10, 1, 100 ) ) {
1127
1128 std::vector<point> candidate_positions =
1129 squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) );
1130 for( point candidate_position : candidate_positions ) {
1131 field &target_field = get_field( tripoint( candidate_position, p.z ) );
1132 // Only shift if there are no bees already there.
1133 // TODO: Figure out a way to merge bee fields without allowing
1134 // Them to effectively move several times in a turn depending
1135 // on iteration direction.
1136 if( !target_field.find_field( fd_bees ) ) {
1137 add_field( tripoint( candidate_position, p.z ), fd_bees,
1138 cur.get_field_intensity(), cur.get_field_age() );
1139 cur.set_field_intensity( 0 );
1140 break;
1141 }
1142 }
1143 } else {
1144 spread_gas( cur, p, 5, 0_turns, sblk );
1145 }
1146 }
1147 }
1148 if( cur_fd_type_id == fd_incendiary ) {
1149 // Needed for variable scope
1150 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
1151 if( has_flag( TFLAG_FLAMMABLE, dst ) ||
1152 has_flag( TFLAG_FLAMMABLE_ASH, dst ) ||
1153 has_flag( TFLAG_FLAMMABLE_HARD, dst ) ) {
1154 add_field( dst, fd_fire, 1 );
1155 }
1156
1157 // Check piles for flammable items and set those on fire
1158 if( flammable_items_at( dst ) ) {
1159 add_field( dst, fd_fire, 1 );
1160 }
1161
1163 }
1164 if( cur_fd_type_id == fd_fungicidal_gas ) {
1165 // Check the terrain and replace it accordingly to simulate the fungus dieing off
1166 const ter_t &ter = map_tile.get_ter_t();
1167 const furn_t &frn = map_tile.get_furn_t();
1168 const int intensity = cur.get_field_intensity();
1169 if( ter.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1170 ter_set( p, t_dirt );
1171 }
1172 if( frn.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1173 furn_set( p, f_null );
1174 }
1175 }
1176
1177 cur.set_field_age( cur.get_field_age() + 1_turns );
1178 auto &fdata = cur.get_field_type().obj();
1179 if( fdata.half_life > 0_turns && cur.get_field_age() > 0_turns &&
1180 dice( 2, to_turns<int>( cur.get_field_age() ) ) > to_turns<int>( fdata.half_life ) ) {
1181 cur.set_field_age( 0_turns );
1183 }
1184 if( !cur.is_field_alive() ) {
1185 --current_submap->field_count;
1186 curfield.remove_field( it++ );
1187 } else {
1188 ++it;
1189 }
1190 }
1191
1192 if( dirty_transparency_cache ) {
1194 set_seen_cache_dirty( thep );
1195 }
1196 }
1197 }
1198 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
1199 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
1200 for( int z = std::max( submap.z - 1, minz ); z <= std::min( submap.z + 1, maxz ); ++z ) {
1201 auto &field_cache = get_cache( z ).field_cache;
1202 for( int y = std::max( submap.y - 1, 0 ); y <= std::min( submap.y + 1, MAPSIZE - 1 ); ++y ) {
1203 for( int x = std::max( submap.x - 1, 0 ); x <= std::min( submap.x + 1, MAPSIZE - 1 ); ++x ) {
1204 if( get_submap_at_grid( { x, y, z } )->field_count > 0 ) {
1205 field_cache.set( x + y * MAPSIZE );
1206 } else {
1207 field_cache.reset( x + y * MAPSIZE );
1208 }
1209 }
1210 }
1211 }
1212 sblk.commit_modifications();
1213}
bool gas_can_spread()
Definition: field.h:93
time_duration intensity_upgrade_duration() const
Definition: field.cpp:44
mongroup_id monster_spawn_group() const
Definition: field.cpp:64
time_duration get_underwater_age_speedup() const
Definition: field.h:97
int monster_spawn_count() const
Definition: field.cpp:54
time_duration mod_field_age(const time_duration &mod_age)
Adds given value to age.
Definition: field.h:73
int intensity_upgrade_chance() const
Definition: field.cpp:39
int monster_spawn_radius() const
Definition: field.cpp:59
int monster_spawn_chance() const
Definition: field.cpp:49
std::map< field_type_id, field_entry >::iterator begin()
Definition: field.cpp:251
std::map< field_type_id, field_entry >::iterator end()
Definition: field.cpp:261
void spread_fungus(const tripoint &p)
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4554
void set_age(const time_duration &age)
Definition: item.cpp:10005
bool detonate(const tripoint &p, std::vector< item > &drops)
Detonates the item and adds remains (if any) to drops.
Definition: item.cpp:8749
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors(const tripoint &p)
Definition: map_field.cpp:190
void create_hot_air(const tripoint &p, int intensity)
Definition: map_field.cpp:363
bool clear_path(const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
Check whether there's a direct line of sight between F and T with the additional movecost restraints.
Definition: map.cpp:6505
void spread_gas(field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
Definition: map_field.cpp:251
void create_burnproducts(const tripoint &p, const item &fuel, const units::mass &burned_mass)
Definition: map_field.cpp:96
field_type_id fd_laser
Definition: field_type.cpp:359
field_type_id fd_plasma
Definition: field_type.cpp:358
field_type_id fd_null
Definition: field_type.cpp:335
std::vector< point > squares_in_direction(point p1, point p2)
Definition: line.cpp:589
static const itype_id itype_rock("rock")
static bool check_flammable(const map_data_common_t &t)
Definition: map_field.cpp:354
static const std::string flag_FUNGUS("FUNGUS")
furn_id f_ash
Definition: mapdata.cpp:1099
ter_id t_pit
Definition: mapdata.cpp:627
@ TFLAG_FLAMMABLE_HARD
Definition: mapdata.h:294
@ TFLAG_FLAMMABLE
Definition: mapdata.h:277
@ TFLAG_FLAMMABLE_ASH
Definition: mapdata.h:289
@ TFLAG_FIRE_CONTAINER
Definition: mapdata.h:293
bool acid(monster *z)
Definition: monattack.cpp:587
bool get_transparent(int level=0) const
Definition: field_type.h:204
int percent_spread
Definition: field_type.h:157
field_type_id wandering_field
Definition: field_type.h:182
std::tuple< int, std::string, time_duration, std::string > npc_complain_data
Definition: field_type.h:170
time_duration outdoor_age_speedup
Definition: field_type.h:155
int apply_slime_factor
Definition: field_type.h:158
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
size_t get_item_count() const
Definition: submap.h:304
ter_id get_ter() const
Definition: submap.h:260

References _, abs_sub, mattack::acid(), add_field(), add_item_or_charges(), add_msg(), add_spawn(), adjust_radiation(), scent_block::apply_slime(), field_type::apply_slime_factor, field::begin(), item_stack::begin(), check_flammable(), clear_path(), scent_block::commit_modifications(), detail::count(), create_burnproducts(), create_hot_air(), vehicle::damage(), debugmsg, destroy(), destroyed, item::detonate(), dice(), field_type::dirty_transparency_cache, field::displayed_field_type(), DT_BASH, DT_HEAT, eight_horizontal_neighbors, field::end(), item_stack::end(), map_stack::erase(), explosive, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), f_ash, f_null, fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_fire_vent, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_gas_vent, fd_incendiary, fd_insecticidal_gas, fd_laser, fd_nuke_gas, fd_null, fd_plasma, fd_push_items, fd_relax_gas, fd_shock_vent, fd_smoke, fd_smoke_vent, fd_tear_gas, fd_toxic_gas, fd_web, field_at(), level_cache::field_cache, submap::field_count, maptile::find_field(), field::find_field(), flag_FUNGUS(), flammable_items_at(), fire_data::fuel_produced, furn_set(), g, field_entry::gas_can_spread(), get_cache(), get_field(), submap::get_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_item_count(), get_map(), get_neighbors(), get_submap_at_grid(), maptile::get_ter(), maptile::get_ter_t(), field_type::get_transparent(), field_entry::get_underwater_age_speedup(), MonsterGroupManager::GetResultFromGroup(), map_data_common_t::has_flag(), has_flag(), i_at(), int_id< T >::id(), ter_t::id, string_id< T >::id(), impassable(), field_entry::intensity_upgrade_chance(), field_entry::intensity_upgrade_duration(), field_entry::is_field_alive(), itype_rock, m_bad, MAPSIZE, maptile_at_internal(), field_entry::mod_field_age(), field_entry::monster_spawn_chance(), field_entry::monster_spawn_count(), field_entry::monster_spawn_group(), field_entry::monster_spawn_radius(), MonsterGroupResult::name, field_type::npc_complain_data, int_id< T >::obj(), obstructed_by_vehicle_rotation(), calendar::once_every(), one_in(), field_type::outdoor_age_speedup, OVERMAP_DEPTH, OVERMAP_HEIGHT, MonsterGroupResult::pack_size, passable(), field_type::percent_spread, point_zero, points_in_radius(), maptile::pos_, random_entry(), random_entry_removed(), random_point(), field::remove_field(), rl_dist(), rng(), roll_remainder(), SEEX, SEEY, item::set_age(), field_entry::set_field_age(), field_entry::set_field_intensity(), set_seen_cache_dirty(), set_transparency_cache_dirty(), spawn_items(), fungal_effects::spread_fungus(), spread_gas(), squares_in_direction(), t_dirt, t_open_air, t_pit, ter(), ter_furn_has_flag(), ter_set(), TFLAG_ALLOW_FIELD_EFFECT, TFLAG_FIRE_CONTAINER, TFLAG_FLAMMABLE, TFLAG_FLAMMABLE_ASH, TFLAG_FLAMMABLE_HARD, TFLAG_NO_FLOOR, TFLAG_SEALED, TFLAG_SWIMMABLE, item::tname(), valid_move(), veh_at_internal(), field_type::wandering_field, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, tripoint::z, and zlevels.

Referenced by process_fields().

◆ process_items()

void map::process_items ( )

Definition at line 4677 of file map.cpp.

4678{
4679 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
4680 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
4681 for( int gz = minz; gz <= maxz; ++gz ) {
4682 level_cache &cache = access_cache( gz );
4683 std::set<tripoint> submaps_with_vehicles;
4684 for( vehicle *this_vehicle : cache.vehicle_list ) {
4685 tripoint pos = this_vehicle->global_pos3();
4686 submaps_with_vehicles.emplace( pos.x / SEEX, pos.y / SEEY, pos.z );
4687 }
4688 for( const tripoint &pos : submaps_with_vehicles ) {
4689 submap *const current_submap = get_submap_at_grid( pos );
4690 // Vehicles first in case they get blown up and drop active items on the map.
4691 process_items_in_vehicles( *current_submap );
4692 }
4693 }
4694 // Making a copy, in case the original variable gets modified during `process_items_in_submap`
4695 const std::set<tripoint> submaps_with_active_items_copy = submaps_with_active_items;
4696 for( const tripoint &abs_pos : submaps_with_active_items_copy ) {
4697 const tripoint local_pos = abs_pos - abs_sub.xy();
4698 submap *const current_submap = get_submap_at_grid( local_pos );
4699 if( !current_submap->active_items.empty() ) {
4700 process_items_in_submap( *current_submap, local_pos );
4701 }
4702 }
4703}
void process_items_in_vehicles(submap &current_submap)
Definition: map.cpp:4740
void process_items_in_submap(submap &current_submap, const tripoint &gridp)
Definition: map.cpp:4720

References abs_sub, access_cache(), submap::active_items, active_item_cache::empty(), get_submap_at_grid(), vehicle::global_pos3(), OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::pos, process_items_in_submap(), process_items_in_vehicles(), SEEX, SEEY, submaps_with_active_items, level_cache::vehicle_list, tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_items_in_submap()

void map::process_items_in_submap ( submap current_submap,
const tripoint gridp 
)
private

Definition at line 4720 of file map.cpp.

4721{
4722 // Get a COPY of the active item list for this submap.
4723 // If more are added as a side effect of processing, they are ignored this turn.
4724 // If they are destroyed before processing, they don't get processed.
4725 std::vector<item_reference> active_items = current_submap.active_items.get_for_processing();
4726 const point grid_offset( gridp.x * SEEX, gridp.y * SEEY );
4727 for( item_reference &active_item_ref : active_items ) {
4728 if( !active_item_ref.item_ref ) {
4729 // The item was destroyed, so skip it.
4730 continue;
4731 }
4732
4733 const tripoint map_location = tripoint( grid_offset + active_item_ref.location, gridp.z );
4734 temperature_flag flag = temperature_flag_at_point( *this, map_location );
4735 map_stack items = i_at( map_location );
4736 process_map_items( items, active_item_ref.item_ref, map_location, flag );
4737 }
4738}
std::vector< item_reference > get_for_processing()
Returns the first size() / processing_speed() elements of each list, rounded up.
static bool process_map_items(item_stack &items, safe_reference< item > &item_ref, const tripoint &location, const temperature_flag flag)
Definition: map.cpp:4563

References submap::active_items, active_item_cache::get_for_processing(), i_at(), process_map_items(), SEEX, SEEY, temperature_flag_at_point(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by process_items().

◆ process_items_in_vehicle()

void map::process_items_in_vehicle ( vehicle cur_veh,
submap current_submap 
)
private

Definition at line 4761 of file map.cpp.

4762{
4763 const bool engine_heater_is_on = cur_veh.has_part( "E_HEATER", true ) && cur_veh.engine_on;
4764 for( const vpart_reference &vp : cur_veh.get_any_parts( VPFLAG_FLUIDTANK ) ) {
4765 vp.part().process_contents( vp.pos(), engine_heater_is_on );
4766 }
4767
4768 auto cargo_parts = cur_veh.get_parts_including_carried( VPFLAG_CARGO );
4769 for( const vpart_reference &vp : cargo_parts ) {
4770 process_vehicle_items( cur_veh, vp.part_index() );
4771 }
4772
4773 for( item_reference &active_item_ref : cur_veh.active_items.get_for_processing() ) {
4774 if( empty( cargo_parts ) ) {
4775 return;
4776 } else if( !active_item_ref.item_ref ) {
4777 // The item was destroyed, so skip it.
4778 continue;
4779 }
4780 const auto it = std::find_if( begin( cargo_parts ),
4781 end( cargo_parts ), [&]( const vpart_reference & part ) {
4782 return active_item_ref.location == part.mount();
4783 } );
4784
4785 if( it == end( cargo_parts ) ) {
4786 continue; // Can't find a cargo part matching the active item.
4787 }
4788 const item &target = *active_item_ref.item_ref;
4789 // Find the cargo part and coordinates corresponding to the current active item.
4790 const vehicle_part &pt = it->part();
4791 const tripoint item_loc = it->pos();
4792 auto items = cur_veh.get_items( static_cast<int>( it->part_index() ) );
4794 if( target.is_food() || target.is_food_container() || target.is_corpse() ) {
4795 const vpart_info &pti = pt.info();
4796 if( engine_heater_is_on ) {
4798 }
4799
4800 if( pt.enabled && pti.has_flag( VPFLAG_FRIDGE ) ) {
4802 } else if( pt.enabled && pti.has_flag( VPFLAG_FREEZER ) ) {
4804 }
4805 }
4806 if( !process_map_items( items, active_item_ref.item_ref, item_loc, flag ) ) {
4807 // If the item was NOT destroyed, we can skip the remainder,
4808 // which handles fallout from the vehicle being damaged.
4809 continue;
4810 }
4811
4812 // item does not exist anymore, might have been an exploding bomb,
4813 // check if the vehicle is still valid (does exist)
4814 if( !current_submap.contains_vehicle( &cur_veh ) ) {
4815 // Nope, vehicle is not in the vehicle list of the submap,
4816 // it might have moved to another submap (unlikely)
4817 // or be destroyed, anyway it does not need to be processed here
4818 return;
4819 }
4820
4821 // Vehicle still valid, reload the list of cargo parts,
4822 // the list of cargo parts might have changed (imagine a part with
4823 // a low index has been removed by an explosion, all the other
4824 // parts would move up to fill the gap).
4825 cargo_parts = cur_veh.get_any_parts( VPFLAG_CARGO );
4826 }
4827}
bool is_food_container() const
Definition: item.cpp:6608
bool is_corpse() const
Whether this is a corpse item.
Definition: item.cpp:6620
bool contains_vehicle(vehicle *)
Definition: submap.cpp:255
bool engine_on
Definition: vehicle.h:2014
vehicle_part_with_feature_range< std::string > get_parts_including_carried(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are not broken or remove...
Definition: vehicle.cpp:2731
bool has_part(const std::string &flag, bool enabled=false) const
Check if vehicle has at least one unbroken part with specified flag.
Definition: vehicle.cpp:2561
active_item_cache active_items
Definition: vehicle.h:1889
vehicle_part_with_feature_range< std::string > get_any_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and not removed.
Definition: vehicle.cpp:2745
point mount() const
Returns the mount point: the point in the vehicles own coordinate system.
Definition: vehicle.cpp:6791
static void process_vehicle_items(vehicle &cur_veh, int part)
Definition: map.cpp:4578
const vpart_info & info() const
Get part definition common to all parts of this type.
bool enabled
Definition: vehicle.h:412
@ VPFLAG_FLUIDTANK
Definition: veh_type.h:73
@ VPFLAG_FREEZER
Definition: veh_type.h:58
@ VPFLAG_FRIDGE
Definition: veh_type.h:57

References vehicle::active_items, submap::contains_vehicle(), vehicle_part::enabled, vehicle::engine_on, vehicle::get_any_parts(), active_item_cache::get_for_processing(), vehicle::get_items(), vehicle::get_parts_including_carried(), vpart_info::has_flag(), vehicle::has_part(), vehicle_part::info(), item::is_corpse(), item::is_food(), item::is_food_container(), vpart_position::mount(), process_map_items(), process_vehicle_items(), TEMP_FREEZER, TEMP_FRIDGE, TEMP_HEATER, TEMP_NORMAL, VPFLAG_CARGO, VPFLAG_FLUIDTANK, VPFLAG_FREEZER, and VPFLAG_FRIDGE.

Referenced by process_items_in_vehicles().

◆ process_items_in_vehicles()

void map::process_items_in_vehicles ( submap current_submap)
private

Definition at line 4740 of file map.cpp.

4741{
4742 // a copy, important if the vehicle list changes because a
4743 // vehicle got destroyed by a bomb (an active item!), this list
4744 // won't change, but veh_in_nonant will change.
4745 std::vector<vehicle *> vehicles;
4746 for( const auto &veh : current_submap.vehicles ) {
4747 vehicles.push_back( veh.get() );
4748 }
4749 for( auto &cur_veh : vehicles ) {
4750 if( !current_submap.contains_vehicle( cur_veh ) ) {
4751 // vehicle not in the vehicle list of the nonant, has been
4752 // destroyed (or moved to another nonant?)
4753 // Can't be sure that it still exists, so skip it
4754 continue;
4755 }
4756
4757 process_items_in_vehicle( *cur_veh, current_submap );
4758 }
4759}
void process_items_in_vehicle(vehicle &cur_veh, submap &current_submap)
Definition: map.cpp:4761

References submap::contains_vehicle(), process_items_in_vehicle(), and submap::vehicles.

Referenced by process_items().

◆ produce_sap()

void map::produce_sap ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Produce sap on tapped maple trees.

Parameters
pLocation of tapped tree
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7354 of file map.cpp.

7355{
7356 if( time_since_last_actualize <= 0_turns ) {
7357 return;
7358 }
7359
7360 if( t_tree_maple_tapped != ter( p ) ) {
7361 return;
7362 }
7363
7364 // Amount of maple sap liters produced per season per tap
7365 static const int maple_sap_per_season = 56;
7366
7367 // How many turns to produce 1 charge (250 ml) of sap?
7368 const time_duration producing_length = 0.75 * calendar::season_length();
7369
7370 const time_duration turns_to_produce = producing_length / ( maple_sap_per_season * 4 );
7371
7372 // How long of this time_since_last_actualize have we been in the producing period (late winter, early spring)?
7373 time_duration time_producing = 0_turns;
7374
7375 if( time_since_last_actualize >= calendar::year_length() ) {
7376 time_producing = producing_length;
7377 } else {
7378 // We are only producing sap on the intersection with the sap producing season.
7379 const time_duration early_spring_end = 0.5f * calendar::season_length();
7380 const time_duration late_winter_start = 3.75f * calendar::season_length();
7381
7382 const time_point last_actualize = calendar::turn - time_since_last_actualize;
7383 const time_duration last_actualize_tof = time_past_new_year( last_actualize );
7384 bool last_producing = (
7385 last_actualize_tof >= late_winter_start ||
7386 last_actualize_tof < early_spring_end
7387 );
7388 const time_duration current_tof = time_past_new_year( calendar::turn );
7389 bool current_producing = (
7390 current_tof >= late_winter_start ||
7391 current_tof < early_spring_end
7392 );
7393
7394 const time_duration non_producing_length = 3.25 * calendar::season_length();
7395
7396 if( last_producing && current_producing ) {
7397 if( time_since_last_actualize < non_producing_length ) {
7398 time_producing = time_since_last_actualize;
7399 } else {
7400 time_producing = time_since_last_actualize - non_producing_length;
7401 }
7402 } else if( !last_producing && !current_producing ) {
7403 if( time_since_last_actualize > non_producing_length ) {
7404 time_producing = time_since_last_actualize - non_producing_length;
7405 }
7406 } else if( last_producing && !current_producing ) {
7407 // We hit the end of early spring
7408 if( last_actualize_tof < early_spring_end ) {
7409 time_producing = early_spring_end - last_actualize_tof;
7410 } else {
7411 time_producing = calendar::year_length() - last_actualize_tof + early_spring_end;
7412 }
7413 } else if( !last_producing && current_producing ) {
7414 // We hit the start of late winter
7415 if( current_tof >= late_winter_start ) {
7416 time_producing = current_tof - late_winter_start;
7417 } else {
7418 time_producing = 0.25f * calendar::season_length() + current_tof;
7419 }
7420 }
7421 }
7422
7423 int new_charges = roll_remainder( time_producing / turns_to_produce );
7424 // Not enough time to produce 1 charge of sap
7425 if( new_charges <= 0 ) {
7426 return;
7427 }
7428
7429 item sap( "maple_sap", calendar::turn );
7430
7431 // Is there a proper container?
7432 auto items = i_at( p );
7433 for( auto &it : items ) {
7434 if( it.is_bucket() || it.is_watertight_container() ) {
7435 const int capacity = it.get_remaining_capacity_for_liquid( sap, true );
7436 if( capacity > 0 ) {
7437 new_charges = std::min( new_charges, capacity );
7438
7439 // The environment might have poisoned the sap with animals passing by, insects, leaves or contaminants in the ground
7440 sap.poison = one_in( 10 ) ? 1 : 0;
7441 sap.charges = new_charges;
7442
7443 it.fill_with( sap );
7444 }
7445 // Only fill up the first container.
7446 break;
7447 }
7448 }
7449}
time_duration time_past_new_year(const time_point &p)
Definition: calendar.h:502
A point in the game time.
Definition: calendar.h:431
ter_id t_tree_maple_tapped
Definition: mapdata.cpp:683
time_duration year_length()
Definition: calendar.cpp:461
time_duration season_length()
Definition: calendar.cpp:466

References item::charges, i_at(), one_in(), item::poison, roll_remainder(), calendar::season_length(), t_tree_maple_tapped, ter(), time_past_new_year(), calendar::turn, and calendar::year_length().

Referenced by actualize().

◆ propagate_field()

void map::propagate_field ( const tripoint center,
const field_type_id type,
int  amount,
int  max_intensity = 0 
)

Definition at line 1940 of file map_field.cpp.

1942{
1943 using gas_blast = std::pair<float, tripoint>;
1944 std::priority_queue<gas_blast, std::vector<gas_blast>, pair_greater_cmp_first> open;
1945 std::set<tripoint> closed;
1946 open.push( { 0.0f, center } );
1947
1948 const bool not_gas = type.obj().phase != GAS;
1949
1950 while( amount > 0 && !open.empty() ) {
1951 if( closed.count( open.top().second ) ) {
1952 open.pop();
1953 continue;
1954 }
1955
1956 // All points with equal gas intensity should propagate at the same time
1957 std::list<gas_blast> gas_front;
1958 gas_front.push_back( open.top() );
1959 const int cur_intensity = get_field_intensity( open.top().second, type );
1960 open.pop();
1961 while( !open.empty() && get_field_intensity( open.top().second, type ) == cur_intensity ) {
1962 if( closed.count( open.top().second ) == 0 ) {
1963 gas_front.push_back( open.top() );
1964 }
1965
1966 open.pop();
1967 }
1968
1969 int increment = std::max<int>( 1, amount / gas_front.size() );
1970
1971 while( !gas_front.empty() ) {
1972 gas_blast gp = random_entry_removed( gas_front );
1973 closed.insert( gp.second );
1974 const int cur_intensity = get_field_intensity( gp.second, type );
1975 if( cur_intensity < max_intensity ) {
1976 const int bonus = std::min( max_intensity - cur_intensity, increment );
1977 mod_field_intensity( gp.second, type, bonus );
1978 amount -= bonus;
1979 } else {
1980 amount--;
1981 }
1982
1983 if( amount <= 0 ) {
1984 return;
1985 }
1986
1987 static const std::array<int, 8> x_offset = {{ -1, 1, 0, 0, 1, -1, -1, 1 }};
1988 static const std::array<int, 8> y_offset = {{ 0, 0, -1, 1, -1, 1, -1, 1 }};
1989 for( size_t i = 0; i < 8; i++ ) {
1990 tripoint pt = gp.second + point( x_offset[ i ], y_offset[ i ] );
1991 if( closed.count( pt ) > 0 ) {
1992 continue;
1993 }
1994
1995 if( impassable( pt ) && ( not_gas || !has_flag( TFLAG_PERMEABLE, pt ) ) ) {
1996 closed.insert( pt );
1997 continue;
1998 }
1999 if( !obstructed_by_vehicle_rotation( gp.second, pt ) ) {
2000 open.push( { static_cast<float>( rl_dist( center, pt ) ), pt } );
2001 }
2002 }
2003 }
2004 }
2005}
@ GAS
Definition: enums.h:175
Greater-than comparison operator; required by the sort interface.
Definition: cata_utility.h:20

References center, GAS, get_field_intensity(), has_flag(), impassable(), mod_field_intensity(), obstructed_by_vehicle_rotation(), open(), random_entry_removed(), rl_dist(), TFLAG_PERMEABLE, and type.

Referenced by computer_session::action_irradiator(), and emit_field().

◆ propagate_suspension_check()

void map::propagate_suspension_check ( const tripoint point)

Checks surrounding tiles for suspension, and has them check for collapse.

!!Should only be called after the tile at this point has been destroyed!!

Definition at line 3004 of file map.cpp.

3005{
3006 for( const tripoint &neighbor : points_in_radius( point, 1 ) ) {
3007 if( neighbor != point && has_flag( TFLAG_SUSPENDED, neighbor ) ) {
3008 collapse_invalid_suspension( neighbor );
3009 }
3010 }
3011}

References collapse_invalid_suspension(), has_flag(), points_in_radius(), and TFLAG_SUSPENDED.

Referenced by bash_ter_success(), collapse_at(), and collapse_invalid_suspension().

◆ put_items_from_loc()

std::vector< item * > map::put_items_from_loc ( const item_group_id loc,
const tripoint p,
const time_point turn = calendar::start_of_cataclysm 
)

Place items from an item group at p.

Places as much items as the item group says. (Most item groups are distributions and will only create one item.)

Parameters
locCurrent location of items
pDestination of items
turnThe birthday that the created items shall have.
Returns
Vector of pointers to placed items (can be empty, but no nulls).

Definition at line 5604 of file mapgen.cpp.

5606{
5607 const auto items = item_group::items_from( loc, turn );
5608 return spawn_items( p, items );
5609}

References item_group::items_from(), spawn_items(), and calendar::turn.

Referenced by add_corpse(), activity_handlers::forage_finish(), mapgen_cavern(), MapExtras::mx_corpses(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), and place_items().

◆ rad_scorch()

void map::rad_scorch ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Radiation-related plant (and fungus?) death.

Definition at line 7451 of file map.cpp.

7452{
7453 const int rads = get_radiation( p );
7454 if( rads == 0 ) {
7455 return;
7456 }
7457
7458 // TODO: More interesting rad scorch chance - base on season length?
7459 if( !x_in_y( 1.0 * rads * rads * time_since_last_actualize, 91_days ) ) {
7460 return;
7461 }
7462
7463 // First destroy the farmable plants (those are furniture)
7464 // TODO: Rad-resistant mutant plants (that produce radioactive fruit)
7465 const furn_t &fid = furn( p ).obj();
7466 if( fid.has_flag( "PLANT" ) ) {
7467 i_clear( p );
7468 furn_set( p, f_null );
7469 }
7470
7471 const ter_id tid = ter( p );
7472 // TODO: De-hardcode this
7473 static const std::map<ter_id, ter_str_id> dies_into {{
7474 {t_grass, ter_str_id( "t_dirt" )},
7475 {t_tree_young, ter_str_id( "t_dirt" )},
7476 {t_tree_pine, ter_str_id( "t_tree_deadpine" )},
7477 {t_tree_birch, ter_str_id( "t_tree_birch_harvested" )},
7478 {t_tree_willow, ter_str_id( "t_tree_willow_harvested" )},
7479 {t_tree_hickory, ter_str_id( "t_tree_hickory_dead" )},
7480 {t_tree_hickory_harvested, ter_str_id( "t_tree_hickory_dead" )},
7481 }};
7482
7483 const auto iter = dies_into.find( tid );
7484 if( iter != dies_into.end() ) {
7485 ter_set( p, iter->second );
7486 return;
7487 }
7488
7489 const ter_t &tr = tid.obj();
7490 if( tr.has_flag( "SHRUB" ) ) {
7491 ter_set( p, t_dirt );
7492 } else if( tr.has_flag( "TREE" ) ) {
7493 ter_set( p, ter_str_id( "t_tree_dead" ) );
7494 }
7495}
int get_radiation(const tripoint &p) const
Definition: map.cpp:4131
ter_id t_tree_hickory_harvested
Definition: mapdata.cpp:684
ter_id t_tree_willow
Definition: mapdata.cpp:683
ter_id t_tree_birch
Definition: mapdata.cpp:683
ter_id t_tree_pine
Definition: mapdata.cpp:683
ter_id t_tree_young
Definition: mapdata.cpp:679
ter_id t_tree_hickory
Definition: mapdata.cpp:684
string_id< ter_t > ter_str_id
Definition: mapdata.h:24

References f_null, furn(), furn_set(), get_radiation(), map_data_common_t::has_flag(), i_clear(), int_id< T >::obj(), t_dirt, t_grass, t_tree_birch, t_tree_hickory, t_tree_hickory_harvested, t_tree_pine, t_tree_willow, t_tree_young, ter(), ter_set(), and x_in_y().

Referenced by actualize().

◆ random_outdoor_tile()

point map::random_outdoor_tile ( )

Definition at line 2791 of file map.cpp.

2792{
2793 std::vector<point> options;
2794 for( const tripoint &p : points_on_zlevel() ) {
2795 if( is_outside( p.xy() ) ) {
2796 options.push_back( p.xy() );
2797 }
2798 }
2800}
std::string options()
Definition: path_info.cpp:230

References is_outside(), PATH_INFO::options(), point_north_west, points_on_zlevel(), and random_entry().

◆ ranged_target_size()

double map::ranged_target_size ( const tripoint p) const

Size of map objects at p for purposes of ranged combat.

Size is in percentage of tile: if 1.0, all attacks going through tile should hit map objects on it, if 0.0 there is nothing to be hit (air/water).

Definition at line 2019 of file map.cpp.

2020{
2021 if( impassable( p ) ) {
2022 return 1.0;
2023 }
2024
2025 if( !has_floor( p ) ) {
2026 return 0.0;
2027 }
2028
2029 // TODO: Handle cases like shrubs, trees, furniture, sandbags...
2030 return 0.1;
2031}

References has_floor(), and impassable().

Referenced by projectile_attack().

◆ reachable_flood_steps()

void map::reachable_flood_steps ( std::vector< tripoint > &  reachable_pts,
const tripoint f,
int  range,
int  cost_min,
int  cost_max 
) const

Populates a vector of points that are reachable within a number of steps from a point.

It could be generalized to take advantage of z levels, but would need some additional code to detect whether a valid transition was on a tile.

Does the following:

  1. Checks if a point is reachable using a flood fill and if it is, adds it to a vector.

Definition at line 6395 of file map.cpp.

6397{
6398 struct pq_item {
6399 int dist;
6400 int ndx;
6401 };
6402 struct pq_item_comp {
6403 bool operator()( const pq_item &left, const pq_item &right ) {
6404 return left.dist > right.dist;
6405 }
6406 };
6407 using PQ_type = std::priority_queue< pq_item, std::vector<pq_item>, pq_item_comp>;
6408
6409 // temp buffer for grid
6410 const int grid_dim = range * 2 + 1;
6411 // init to -1 as "not visited yet"
6412 std::vector< int > t_grid( static_cast<size_t>( grid_dim * grid_dim ), -1 );
6413 const tripoint origin_offset = {range, range, 0};
6414 const int initial_visit_distance = range * range; // Large unreachable value
6415
6416 // Fill positions that are visitable with initial_visit_distance
6417 for( const tripoint &p : points_in_radius( f, range ) ) {
6418 const tripoint tp = { p.xy(), f.z };
6419 const int tp_cost = move_cost( tp );
6420 // rejection conditions
6421 if( tp_cost < cost_min || tp_cost > cost_max || !has_floor_or_support( tp ) ) {
6422 continue;
6423 }
6424 // set initial cost for grid point
6425 tripoint origin_relative = tp - f;
6426 origin_relative += origin_offset;
6427 int ndx = origin_relative.x + origin_relative.y * grid_dim;
6428 t_grid[ ndx ] = initial_visit_distance;
6429 }
6430
6431 auto gen_neighbors = []( const pq_item & elem, int grid_dim, pq_item * neighbors ) {
6432 // Up to 8 neighbors
6433 int new_cost = elem.dist + 1;
6434 // *INDENT-OFF*
6435 int ox[8] = {
6436 -1, 0, 1,
6437 -1, 1,
6438 -1, 0, 1
6439 };
6440 int oy[8] = {
6441 -1, -1, -1,
6442 0, 0,
6443 1, 1, 1
6444 };
6445 // *INDENT-ON*
6446
6447 point e( elem.ndx % grid_dim, elem.ndx / grid_dim );
6448 for( int i = 0; i < 8; ++i ) {
6449 point n( e + point( ox[i], oy[i] ) );
6450
6451 int ndx = n.x + n.y * grid_dim;
6452 neighbors[i] = { new_cost, ndx };
6453 }
6454 };
6455
6456 PQ_type pq( pq_item_comp{} );
6457 pq_item first_item{ 0, range + range * grid_dim };
6458 pq.push( first_item );
6459 pq_item neighbor_elems[8];
6460
6461 while( !pq.empty() ) {
6462 const pq_item item = pq.top();
6463 pq.pop();
6464
6465 if( t_grid[ item.ndx ] == initial_visit_distance ) {
6466 t_grid[ item.ndx ] = item.dist;
6467 if( item.dist + 1 < range ) {
6468 gen_neighbors( item, grid_dim, neighbor_elems );
6469 for( pq_item neighbor_elem : neighbor_elems ) {
6470 pq.push( neighbor_elem );
6471 }
6472 }
6473 }
6474 }
6475 std::vector<char> o_grid( static_cast<size_t>( grid_dim * grid_dim ), 0 );
6476 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6477 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6478 if( t_grid[ ndx ] != -1 && t_grid[ ndx ] < initial_visit_distance ) {
6479 // set self and neighbors to 1
6480 for( int dy = -1; dy <= 1; ++dy ) {
6481 for( int dx = -1; dx <= 1; ++dx ) {
6482 int tx = dx + x;
6483 int ty = dy + y;
6484
6485 if( tx >= 0 && tx < grid_dim && ty >= 0 && ty < grid_dim ) {
6486 o_grid[ tx + ty * grid_dim ] = 1;
6487 }
6488 }
6489 }
6490 }
6491 }
6492 }
6493
6494 // Now go over again to pull out all of the reachable points
6495 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6496 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6497 if( o_grid[ ndx ] ) {
6498 tripoint t = f - origin_offset + tripoint{ x, y, 0 };
6499 reachable_pts.push_back( t );
6500 }
6501 }
6502 }
6503}

References has_floor_or_support(), left, move_cost(), points_in_radius(), right, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by inventory::form_from_map(), and use_charges().

◆ register_vehicle_zone()

void map::register_vehicle_zone ( vehicle veh,
int  zlev 
)

Definition at line 1016 of file map.cpp.

1017{
1018 auto &ch = get_cache( zlev );
1019 ch.zone_vehicles.insert( veh );
1020}

References get_cache().

Referenced by zone_manager::create_vehicle_loot_zone(), and zone_manager::revert_vzones().

◆ remove_field()

void map::remove_field ( const tripoint p,
const field_type_id field_to_remove 
)

Remove field entry at xy, ignored if the field entry is not present.

Definition at line 5563 of file map.cpp.

5564{
5565 if( !inbounds( p ) ) {
5566 return;
5567 }
5568
5569 point l;
5570 submap *const current_submap = get_submap_at( p, l );
5571
5572 if( current_submap->get_field( l ).remove_field( field_to_remove ) ) {
5573 // Only adjust the count if the field actually existed.
5574 if( !--current_submap->field_count ) {
5575 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5576 p.y / SEEX ) * MAPSIZE ) ) );
5577 }
5578 const auto &fdata = field_to_remove.obj();
5579 if( fdata.dirty_transparency_cache || !fdata.is_transparent() ) {
5582 }
5583 if( fdata.is_dangerous() ) {
5585 }
5586 }
5587}

References level_cache::field_cache, submap::field_count, get_cache(), submap::get_field(), get_submap_at(), inbounds(), MAPSIZE, int_id< T >::obj(), field::remove_field(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_deactivate_shock_vent(), bash_field(), editmap::edit_fld(), iexamine::fireplace(), game::grabbed_furn_move(), MapExtras::mx_house_spider(), MapExtras::mx_spider(), game::process_artifact(), relic_funcs::process_recharge_entry(), explosion_handler::ExplosionProcess::remove_field(), set_field_intensity(), shoot(), smash(), spell_move(), avatar_funcs::try_to_sleep(), and game::walk_move().

◆ remove_rotten_items()

template<typename Container >
void map::remove_rotten_items ( Container &  items,
const tripoint p,
temperature_flag  temperature 
)
protected

Go through the list of items, update their rotten status and remove items that have rotten away completely.

Parameters
itemsitems to remove
pThe point on this map where the items are, used for rot calculation.
temperatureflag that overrides temperature processing at certain locations

Definition at line 7200 of file map.cpp.

7201{
7202 for( auto it = items.begin(); it != items.end(); ) {
7203 if( it->actualize_rot( pnt, temperature, get_weather() ) ) {
7204 if( it->is_comestible() ) {
7205 rotten_item_spawn( *it, pnt );
7206 }
7207 it = i_rem( pnt, it );
7208 } else {
7209 ++it;
7210 }
7211 }
7212}

References get_weather(), i_rem(), and rotten_item_spawn().

Referenced by actualize().

◆ remove_submap_camp()

void map::remove_submap_camp ( const tripoint p)

Definition at line 5678 of file map.cpp.

5679{
5680 get_submap_at( p )->camp.reset();
5681}

References submap::camp, and get_submap_at().

Referenced by basecamp::abandon_camp(), and game::validate_camps().

◆ remove_trap()

void map::remove_trap ( const tripoint p)

Definition at line 5371 of file map.cpp.

5372{
5373 if( !inbounds( p ) ) {
5374 return;
5375 }
5376
5377 point l;
5378 submap *const current_submap = get_submap_at( p, l );
5379
5380 trap_id tid = current_submap->get_trap( l );
5381 if( tid != tr_null ) {
5382 if( g != nullptr && this == &get_map() ) {
5383 g->u.add_known_trap( p, tr_null.obj() );
5384 }
5385
5386 current_submap->set_trap( l, tr_null );
5387 auto &traps = traplocs[tid.to_i()];
5388 const auto iter = std::find( traps.begin(), traps.end(), p );
5389 if( iter != traps.end() ) {
5390 traps.erase( iter );
5391 }
5392 }
5393}
void set_trap(point p, trap_id trap)
Definition: submap.h:77

References detail::find(), g, get_map(), get_submap_at(), submap::get_trap(), inbounds(), int_id< T >::obj(), submap::set_trap(), int_id< T >::to_i(), tr_null, and traplocs.

Referenced by complete_construction(), vehicle::handle_trap(), trapfunc::map_regen(), mremove_trap(), trap::on_disarmed(), game::process_artifact(), relic_funcs::process_recharge_entry(), and trap_set().

◆ reset_vehicle_cache()

void map::reset_vehicle_cache ( )

Definition at line 313 of file map.cpp.

314{
317
318 // Cache all vehicles
319 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
320 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
321 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
322 auto &ch = get_cache( zlev );
323 for( const auto &elem : ch.vehicle_list ) {
324 elem->adjust_zlevel( 0, tripoint_zero );
325 add_vehicle_to_cache( elem );
326 }
327 }
328}
void clear_vehicle_cache()
Definition: map.cpp:372

References abs_sub, add_vehicle_to_cache(), clear_vehicle_cache(), get_cache(), last_full_vehicle_list_dirty, OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint_zero, tripoint::z, and zlevels.

Referenced by veh_interact::complete_vehicle(), detach_vehicle(), editmap::draw_main_ui_overlay(), load(), loadn(), editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), rotate(), shift(), and vehicle::use_bike_rack().

◆ restock_fruits()

void map::restock_fruits ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Try to grow fruits on static plants (not planted by the player)

Parameters
pPlace to restock
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7340 of file map.cpp.

7341{
7342 const auto &ter = this->ter( p ).obj();
7343 if( !ter.has_flag( TFLAG_HARVESTED ) ) {
7344 return; // Already harvestable. Do nothing.
7345 }
7346 // Make it harvestable again if the last actualization was during a different season or year.
7347 const time_point last_touched = calendar::turn - time_since_last_actualize;
7348 if( season_of_year( calendar::turn ) != season_of_year( last_touched ) ||
7349 time_since_last_actualize >= calendar::season_length() ) {
7350 ter_set( p, ter.transforms_into );
7351 }
7352}
season_type season_of_year(const time_point &p)
Definition: calendar.cpp:547

References int_id< T >::obj(), calendar::season_length(), season_of_year(), ter(), ter_set(), TFLAG_HARVESTED, and calendar::turn.

Referenced by actualize(), and saven().

◆ restore_vision_transparency_cache()

void map::restore_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1505 of file lightmap.cpp.

1507{
1508 auto &map_cache = get_cache( target_z );
1509 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1510 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1511
1512 int i = 0;
1513 for( point adjacent : eight_adjacent_offsets ) {
1514 const tripoint p = center + adjacent;
1515 if( !inbounds( p ) ) {
1516 continue;
1517 }
1518 transparency_cache[p.x][p.y] = vision_restore_cache[i];
1519
1520 if( blocked_restore_cache[i] ) {
1521 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1522 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1523 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1524 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1525 relevant_blocked = false;
1526 }
1527
1528 i++;
1529 }
1530 transparency_cache[center.x][center.y] = vision_restore_cache[8];
1531}

References center, eight_adjacent_offsets, get_cache(), inbounds(), MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ rotate()

void map::rotate ( int  turns,
bool  setpos_safe = false 
)

Rotates this map, and all of its contents, by the specified multiple of 90 degrees.

Parameters
turnsHow many 90-degree turns to rotate the map.

Definition at line 5831 of file mapgen.cpp.

5832{
5833
5834 //Handle anything outside the 1-3 range gracefully; rotate(0) is a no-op.
5835 turns = turns % 4;
5836 if( turns == 0 ) {
5837 return;
5838 }
5839
5840 real_coords rc;
5841 const tripoint &abs_sub = get_abs_sub();
5842 rc.fromabs( point( abs_sub.x * SEEX, abs_sub.y * SEEY ) );
5843
5844 // TODO: This radius can be smaller - how small?
5845 const int radius = HALF_MAPSIZE + 3;
5846 // uses submap coordinates
5847 // TODO: fix point types
5848 const std::vector<shared_ptr_fast<npc>> npcs =
5850 for( const shared_ptr_fast<npc> &i : npcs ) {
5851 npc &np = *i;
5852 const tripoint sq = np.global_square_location();
5853 const point local_sq = getlocal( sq ).xy();
5854
5855 real_coords np_rc;
5856 np_rc.fromabs( sq.xy() );
5857 // Note: We are rotating the entire overmap square (2x2 of submaps)
5858 if( np_rc.om_pos != rc.om_pos || sq.z != abs_sub.z ) {
5859 continue;
5860 }
5861
5862 // OK, this is ugly: we remove the NPC from the whole map
5863 // Then we place it back from scratch
5864 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5865
5866 point old( np_rc.sub_pos );
5867 if( np_rc.om_sub.x % 2 != 0 ) {
5868 old.x += SEEX;
5869 }
5870 if( np_rc.om_sub.y % 2 != 0 ) {
5871 old.y += SEEY;
5872 }
5873
5874 const point new_pos = old .rotate( turns, { SEEX * 2, SEEY * 2 } );
5875 if( setpos_safe ) {
5876 // setpos can't be used during mapgen, but spawn_at_precise clips position
5877 // to be between 0-11,0-11 and teleports NPCs when used inside of update_mapgen
5878 // calls
5879 const tripoint new_global_sq = sq - local_sq + new_pos;
5880 np.setpos( get_map().getlocal( new_global_sq ) );
5881 } else {
5882 // OK, this is ugly: we remove the NPC from the whole map
5883 // Then we place it back from scratch
5884 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5886 np.spawn_at_precise( { abs_sub.xy() }, { new_pos, abs_sub.z } );
5888 }
5889 }
5890
5893
5894 // Move the submaps around.
5895 if( turns == 2 ) {
5898 } else {
5899 point p;
5900 submap tmp;
5901
5903
5904 for( int k = 0; k < 4; ++k ) {
5905 p = p.rotate( turns, { 2, 2 } );
5907 }
5908 }
5909
5910 // Then rotate them and recalculate vehicle positions.
5911 for( int j = 0; j < 2; ++j ) {
5912 for( int i = 0; i < 2; ++i ) {
5913 point p( i, j );
5914 auto sm = get_submap_at_grid( p );
5915
5916 sm->rotate( turns );
5917
5918 for( auto &veh : sm->vehicles ) {
5919 veh->sm_pos = tripoint( p, abs_sub.z );
5920 }
5921
5923 }
5924 }
5926
5927 // rotate zones
5929 mgr.rotate_zones( *this, turns );
5930}
shared_ptr_fast< npc > npc_ptr
Definition: basecamp.h:46
character_id getID() const
Definition: character.cpp:485
void clear_vehicle_list(int zlev)
Definition: map.cpp:390
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:689
void spawn_at_precise(point submap_offset, const tripoint &square)
As spawn_at, but also sets position within the submap.
Definition: npc.cpp:737
tripoint global_square_location() const override
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: npc.cpp:747
std::vector< shared_ptr_fast< npc > > get_npcs_near(const tripoint_abs_sm &p, int radius)
Get all npcs in a area with given radius around given central point.
shared_ptr_fast< npc > remove_npc(const character_id &id)
Find npc by id and if found, erase it from the npc list and return it ( or return nullptr if not foun...
void rotate_zones(map &target_map, int turns)
Definition: clzones.cpp:1052
coords::coord_point< tripoint, coords::origin::abs, coords::sm > tripoint_abs_sm
Definition: coordinates.h:490
static constexpr int HALF_MAPSIZE
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496
point rotate(int turns, point dim={ 1, 1 }) const
Rotate point clockwise.
Definition: point.cpp:10
point om_sub
Definition: coordinates.h:638
void fromabs(point abs)
Definition: coordinates.cpp:3
point om_pos
Definition: coordinates.h:637
point sub_pos
Definition: coordinates.h:635

References abs_sub, clear_vehicle_cache(), clear_vehicle_list(), real_coords::fromabs(), get_abs_sub(), zone_manager::get_manager(), get_map(), overmapbuffer::get_npcs_near(), get_submap_at_grid(), Character::getID(), getlocal(), npc::global_square_location(), HALF_MAPSIZE, overmapbuffer::insert_npc(), real_coords::om_pos, real_coords::om_sub, overmap_buffer, point_east, point_south, point_south_east, point_zero, overmapbuffer::remove_npc(), reset_vehicle_cache(), point::rotate(), zone_manager::rotate_zones(), SEEX, SEEY, npc::setpos(), coords::sm, npc::spawn_at_precise(), real_coords::sub_pos, cata::swap(), update_vehicle_list(), point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by draw_connections(), draw_lab(), draw_office_tower(), draw_triffid(), mapgen_function_json::generate(), mapgen_ants_curved(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_forest_trail_curved(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_parking_lot(), editmap::mapgen_preview(), mapgen_railroad(), mapgen_railroad_bridge(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rotate(), mapgen_sewer_curved(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_subway(), and update_mapgen_function_json::update_map().

◆ rotten_item_spawn()

void map::rotten_item_spawn ( const item item,
const tripoint p 
)

Checks to see if the item that is rotting away generates a creature when it does.

Parameters
itemitem that is spawning creatures
pThe point on this map where the item is and creature will be

Definition at line 7214 of file map.cpp.

7215{
7216 if( g->critter_at( pnt ) != nullptr ) {
7217 return;
7218 }
7219 const auto &comest = item.get_comestible();
7220 mongroup_id mgroup = comest->rot_spawn;
7221 if( !mgroup ) {
7222 return;
7223 }
7224 const int chance = static_cast<int>( comest->rot_spawn_chance *
7225 get_option<float>( "CARRION_SPAWNRATE" ) );
7226 if( rng( 0, 100 ) < chance ) {
7228 add_spawn( spawn_details.name, 1, pnt, false );
7229 if( g->u.sees( pnt ) ) {
7230 if( item.is_seed() ) {
7231 add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() );
7232 } else {
7233 add_msg( m_warning, _( "Something has crawled out of the %s!" ), item.tname() );
7234 }
7235 }
7236 }
7237}
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:10119
std::string get_plant_name() const
The name of the plant as it appears in the various informational menus.
Definition: item.cpp:9788
bool is_seed() const
Whether this is actually a seed, the seed functions won't be of much use for non-seeds.
Definition: item.cpp:9769

References _, add_msg(), add_spawn(), g, item::get_comestible(), item::get_plant_name(), MonsterGroupManager::GetResultFromGroup(), item::is_seed(), m_warning, MonsterGroupResult::name, rng(), and item::tname().

Referenced by grow_plant(), item::process_internal(), and remove_rotten_items().

◆ route()

std::vector< tripoint > map::route ( const tripoint f,
const tripoint t,
const pathfinding_settings settings,
const std::set< tripoint > &  pre_closed = {{ }} 
) const

Calculate the best path using A*.

Parameters
fThe source location from which to path.
tThe destination to which to path.
settingsStructure describing pathfinding parameters.
pre_closedNever path through those points. They can still be the source or the destination.

Definition at line 194 of file pathfinding.cpp.

197{
198 /* TODO: If the origin or destination is out of bound, figure out the closest
199 * in-bounds point and go to that, then to the real origin/destination.
200 */
201 std::vector<tripoint> ret;
202
203 if( f == t || !inbounds( f ) ) {
204 return ret;
205 }
206
207 if( !inbounds( t ) ) {
208 tripoint clipped = t;
209 clip_to_bounds( clipped );
210 return route( f, clipped, settings, pre_closed );
211 }
212 // First, check for a simple straight line on flat ground
213 // Except when the line contains a pre-closed tile - we need to do regular pathing then
214 static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP | PF_SHARP;
215 if( f.z == t.z ) {
216 const auto line_path = line_to( f, t );
217 const auto &pf_cache = get_pathfinding_cache_ref( f.z );
218 // Check all points for any special case (including just hard terrain)
219 if( !( pf_cache.special[f.x][f.y] & non_normal ) &&
220 std::all_of( line_path.begin(), line_path.end(), [&pf_cache]( const tripoint & p ) {
221 return !( pf_cache.special[p.x][p.y] & non_normal );
222 } ) ) {
223 const std::set<tripoint> sorted_line( line_path.begin(), line_path.end() );
224
225 if( is_disjoint( sorted_line, pre_closed ) ) {
226 return line_path;
227 }
228 }
229 }
230
231 // If expected path length is greater than max distance, allow only line path, like above
232 if( rl_dist( f, t ) > settings.max_dist ) {
233 return ret;
234 }
235
236 int max_length = settings.max_length;
237 int bash = settings.bash_strength;
238 int climb_cost = settings.climb_cost;
239 bool doors = settings.allow_open_doors;
240 bool trapavoid = settings.avoid_traps;
241 bool roughavoid = settings.avoid_rough_terrain;
242 bool sharpavoid = settings.avoid_sharp;
243
244 const int pad = 16; // Should be much bigger - low value makes pathfinders dumb!
245 int minx = std::min( f.x, t.x ) - pad;
246 int miny = std::min( f.y, t.y ) - pad;
247 // TODO: Make this way bigger
248 int minz = std::min( f.z, t.z );
249 int maxx = std::max( f.x, t.x ) + pad;
250 int maxy = std::max( f.y, t.y ) + pad;
251 // Same TODO: as above
252 int maxz = std::max( f.z, t.z );
253 clip_to_bounds( minx, miny, minz );
254 clip_to_bounds( maxx, maxy, maxz );
255
256 pathfinder pf( point( minx, miny ), point( maxx, maxy ) );
257 // Make NPCs not want to path through player
258 // But don't make player pathing stop working
259 for( const auto &p : pre_closed ) {
260 if( p.x >= minx && p.x < maxx && p.y >= miny && p.y < maxy ) {
261 pf.close_point( p );
262 }
263 }
264
265 // Start and end must not be closed
266 pf.unclose_point( f );
267 pf.unclose_point( t );
268 pf.add_point( 0, 0, f, f );
269
270 bool done = false;
271
272 do {
273 auto cur = pf.get_next();
274
275 const int parent_index = flat_index( cur );
276 auto &layer = pf.get_layer( cur.z );
277 auto &cur_state = layer.state[parent_index];
278 if( cur_state == ASL_CLOSED ) {
279 continue;
280 }
281
282 if( layer.gscore[parent_index] > max_length ) {
283 // Shortest path would be too long, return empty vector
284 return std::vector<tripoint>();
285 }
286
287 if( cur == t ) {
288 done = true;
289 break;
290 }
291
292 cur_state = ASL_CLOSED;
293
294 const auto &pf_cache = get_pathfinding_cache_ref( cur.z );
295 const auto cur_special = pf_cache.special[cur.x][cur.y];
296
297 int cur_part;
298 const vehicle *cur_veh = veh_at_internal( cur, cur_part );
299
300 // 7 3 5
301 // 1 . 2
302 // 6 4 8
303 constexpr std::array<int, 8> x_offset{{ -1, 1, 0, 0, 1, -1, -1, 1 }};
304 constexpr std::array<int, 8> y_offset{{ 0, 0, -1, 1, -1, 1, -1, 1 }};
305 for( size_t i = 0; i < 8; i++ ) {
306 const tripoint p( cur.x + x_offset[i], cur.y + y_offset[i], cur.z );
307 const int index = flat_index( p );
308
309 // TODO: Remove this and instead have sentinels at the edges
310 if( p.x < minx || p.x >= maxx || p.y < miny || p.y >= maxy ) {
311 continue;
312 }
313
314 if( layer.state[index] == ASL_CLOSED ) {
315 continue;
316 }
317
318 int part = -1;
319 const vehicle *veh = veh_at_internal( p, part );
320 if( cur_veh &&
321 !cur_veh->allowed_move( cur_veh->tripoint_to_mount( cur ), cur_veh->tripoint_to_mount( p ) ) ) {
322 //Trying to squeeze through a vehicle hole, skip this movement but don't close the tile as other paths may lead to it
323 continue;
324 }
325
326 if( veh && veh != cur_veh &&
327 !veh->allowed_move( veh->tripoint_to_mount( cur ), veh->tripoint_to_mount( p ) ) ) {
328 //Same as above but moving into rather than out of a vehicle
329 continue;
330 }
331
332 // Penalize for diagonals or the path will look "unnatural"
333 int newg = layer.gscore[parent_index] + ( ( cur.x != p.x && cur.y != p.y ) ? 1 : 0 );
334
335 const auto p_special = pf_cache.special[p.x][p.y];
336 // TODO: De-uglify, de-huge-n
337 if( !( p_special & non_normal ) ) {
338 // Boring flat dirt - the most common case above the ground
339 newg += 2;
340 } else {
341 if( roughavoid ) {
342 layer.state[index] = ASL_CLOSED; // Close all rough terrain tiles
343 continue;
344 }
345
346 const maptile &tile = maptile_at_internal( p );
347 const auto &terrain = tile.get_ter_t();
348 const auto &furniture = tile.get_furn_t();
349
350 const int cost = move_cost_internal( furniture, terrain, veh, part );
351 // Don't calculate bash rating unless we intend to actually use it
352 const int rating = ( bash == 0 || cost != 0 ) ? -1 :
353 bash_rating_internal( bash, furniture, terrain, false, veh, part );
354
355 if( cost == 0 && rating <= 0 && ( !doors || !terrain.open || !furniture.open ) && veh == nullptr &&
356 climb_cost <= 0 ) {
357 layer.state[index] = ASL_CLOSED; // Close it so that next time we won't try to calculate costs
358 continue;
359 }
360
361 newg += cost;
362 if( cost == 0 ) {
363 if( climb_cost > 0 && p_special & PF_CLIMBABLE ) {
364 // Climbing fences
365 newg += climb_cost;
366 } else if( doors && ( terrain.open || furniture.open ) &&
367 ( !terrain.has_flag( "OPENCLOSE_INSIDE" ) || !furniture.has_flag( "OPENCLOSE_INSIDE" ) ||
368 !is_outside( cur ) ) ) {
369 // Only try to open INSIDE doors from the inside
370 // To open and then move onto the tile
371 newg += 4;
372 } else if( veh != nullptr ) {
373 const auto vpobst = vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part();
374 part = vpobst ? vpobst->part_index() : -1;
375 int dummy = -1;
376 if( doors && veh->part_flag( part, VPFLAG_OPENABLE ) &&
377 ( !veh->part_flag( part, "OPENCLOSE_INSIDE" ) ||
378 veh_at_internal( cur, dummy ) == veh ) ) {
379 // Handle car doors, but don't try to path through curtains
380 newg += 10; // One turn to open, 4 to move there
381 } else if( part >= 0 && bash > 0 ) {
382 // Car obstacle that isn't a door
383 // TODO: Account for armor
384 int hp = veh->cpart( part ).hp();
385 if( hp / 20 > bash ) {
386 // Threshold damage thing means we just can't bash this down
387 layer.state[index] = ASL_CLOSED;
388 continue;
389 } else if( hp / 10 > bash ) {
390 // Threshold damage thing means we will fail to deal damage pretty often
391 hp *= 2;
392 }
393
394 newg += 2 * hp / bash + 8 + 4;
395 } else if( part >= 0 ) {
396 if( !doors || !veh->part_flag( part, VPFLAG_OPENABLE ) ) {
397 // Won't be openable, don't try from other sides
398 layer.state[index] = ASL_CLOSED;
399 }
400
401 continue;
402 }
403 } else if( rating > 1 ) {
404 // Expected number of turns to bash it down, 1 turn to move there
405 // and 5 turns of penalty not to trash everything just because we can
406 newg += ( 20 / rating ) + 2 + 10;
407 } else if( rating == 1 ) {
408 // Desperate measures, avoid whenever possible
409 newg += 500;
410 } else {
411 // Unbashable and unopenable from here
412 if( !doors || !terrain.open || !furniture.open ) {
413 // Or anywhere else for that matter
414 layer.state[index] = ASL_CLOSED;
415 }
416
417 continue;
418 }
419 }
420
421 if( trapavoid && p_special & PF_TRAP ) {
422 const auto &ter_trp = terrain.trap.obj();
423 const auto &trp = ter_trp.is_benign() ? tile.get_trap_t() : ter_trp;
424 if( !trp.is_benign() ) {
425 // For now make them detect all traps
426 if( has_zlevels() && terrain.has_flag( TFLAG_NO_FLOOR ) ) {
427 // Special case - ledge in z-levels
428 // Warning: really expensive, needs a cache
429 if( valid_move( p, tripoint( p.xy(), p.z - 1 ), false, true ) ) {
430 tripoint below( p.xy(), p.z - 1 );
431 if( !has_flag( TFLAG_NO_FLOOR, below ) ) {
432 // Otherwise this would have been a huge fall
433 auto &layer = pf.get_layer( p.z - 1 );
434 // From cur, not p, because we won't be walking on air
435 pf.add_point( layer.gscore[parent_index] + 10,
436 layer.score[parent_index] + 10 + 2 * rl_dist( below, t ),
437 cur, below );
438 }
439
440 // Close p, because we won't be walking on it
441 layer.state[index] = ASL_CLOSED;
442 continue;
443 }
444 } else if( trapavoid ) {
445 // Otherwise it's walkable
446 newg += 500;
447 }
448 }
449 }
450
451 if( sharpavoid && p_special & PF_SHARP ) {
452 layer.state[index] = ASL_CLOSED; // Avoid sharp things
453 }
454
455 }
456
457 // If not visited, add as open
458 // If visited, add it only if we can do so with better score
459 if( layer.state[index] == ASL_NONE || newg < layer.gscore[index] ) {
460 pf.add_point( newg, newg + 2 * rl_dist( p, t ), cur, p );
461 }
462 }
463
464 if( !has_zlevels() || !( cur_special & PF_UPDOWN ) || !settings.allow_climb_stairs ) {
465 // The part below is only for z-level pathing
466 continue;
467 }
468
469 const maptile &parent_tile = maptile_at_internal( cur );
470 const auto &parent_terrain = parent_tile.get_ter_t();
471 if( settings.allow_climb_stairs && cur.z > minz && parent_terrain.has_flag( TFLAG_GOES_DOWN ) ) {
472 tripoint dest( cur.xy(), cur.z - 1 );
473 if( vertical_move_destination<TFLAG_GOES_UP>( *this, dest ) ) {
474 auto &layer = pf.get_layer( dest.z );
475 pf.add_point( layer.gscore[parent_index] + 2,
476 layer.score[parent_index] + 2 * rl_dist( dest, t ),
477 cur, dest );
478 }
479 }
480 if( settings.allow_climb_stairs && cur.z < maxz && parent_terrain.has_flag( TFLAG_GOES_UP ) ) {
481 tripoint dest( cur.xy(), cur.z + 1 );
482 if( vertical_move_destination<TFLAG_GOES_DOWN>( *this, dest ) ) {
483 auto &layer = pf.get_layer( dest.z );
484 pf.add_point( layer.gscore[parent_index] + 2,
485 layer.score[parent_index] + 2 * rl_dist( dest, t ),
486 cur, dest );
487 }
488 }
489 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP ) &&
490 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true ) ) {
491 auto &layer = pf.get_layer( cur.z + 1 );
492 for( size_t it = 0; it < 8; it++ ) {
493 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
494 pf.add_point( layer.gscore[parent_index] + 4,
495 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
496 cur, above );
497 }
498 }
499 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP_UP ) &&
500 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true, true ) ) {
501 auto &layer = pf.get_layer( cur.z + 1 );
502 for( size_t it = 0; it < 8; it++ ) {
503 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
504 pf.add_point( layer.gscore[parent_index] + 4,
505 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
506 cur, above );
507 }
508 }
509 if( cur.z > minz && parent_terrain.has_flag( TFLAG_RAMP_DOWN ) &&
510 valid_move( cur, tripoint( cur.xy(), cur.z - 1 ), false, true, true ) ) {
511 auto &layer = pf.get_layer( cur.z - 1 );
512 for( size_t it = 0; it < 8; it++ ) {
513 const tripoint below( cur.x + x_offset[it], cur.y + y_offset[it], cur.z - 1 );
514 pf.add_point( layer.gscore[parent_index] + 4,
515 layer.score[parent_index] + 4 + 2 * rl_dist( below, t ),
516 cur, below );
517 }
518 }
519
520 } while( !done && !pf.empty() );
521
522 if( done ) {
523 ret.reserve( rl_dist( f, t ) * 2 );
524 tripoint cur = t;
525 // Just to limit max distance, in case something weird happens
526 for( int fdist = max_length; fdist != 0; fdist-- ) {
527 const int cur_index = flat_index( cur );
528 const auto &layer = pf.get_layer( cur.z );
529 const tripoint &par = layer.parent[cur_index];
530 if( cur == f ) {
531 break;
532 }
533
534 ret.push_back( cur );
535 // Jumps are acceptable on 1 z-level changes
536 // This is because stairs teleport the player too
537 if( rl_dist( cur, par ) > 1 && std::abs( cur.z - par.z ) != 1 ) {
538 debugmsg( "Jump in our route! %d:%d:%d->%d:%d:%d",
539 cur.x, cur.y, cur.z, par.x, par.y, par.z );
540 return ret;
541 }
542
543 cur = par;
544 }
545
546 std::reverse( ret.begin(), ret.end() );
547 }
548
549 return ret;
550}
bool has_zlevels() const
Definition: map.h:1635
const pathfinding_cache & get_pathfinding_cache_ref(int zlev) const
Definition: map.cpp:8960
point tripoint_to_mount(const tripoint &p) const
Definition: vehicle.cpp:3131
const vehicle_part & cpart(int part_num) const
Definition: vehicle.cpp:7089
bool part_flag(int p, const std::string &f) const
Definition: vehicle.cpp:2912
bool allowed_move(point from, point to) const
Definition: vehicle.cpp:3221
@ TFLAG_GOES_DOWN
Definition: mapdata.h:308
@ TFLAG_GOES_UP
Definition: mapdata.h:309
Definition: gates.h:28
Definition: overmap.h:50
bool is_disjoint(const Set1 &set1, const Set2 &set2)
constexpr int flat_index(const tripoint &p)
Definition: pathfinding.cpp:34
@ ASL_CLOSED
Definition: pathfinding.cpp:30
@ ASL_NONE
Definition: pathfinding.cpp:28
@ PF_VEHICLE
Definition: pathfinding.h:11
@ PF_WALL
Definition: pathfinding.h:10
@ PF_CLIMBABLE
Definition: pathfinding.h:15
@ PF_UPDOWN
Definition: pathfinding.h:14
@ PF_TRAP
Definition: pathfinding.h:13
@ PF_SHARP
Definition: pathfinding.h:16
@ PF_SLOW
Definition: pathfinding.h:9
@ hp
Drains HP to recharge.
const trap & get_trap_t() const
Definition: submap.h:264
@ VPFLAG_OPENABLE
Definition: veh_type.h:44

References pathfinding_settings::allow_climb_stairs, pathfinding_settings::allow_open_doors, vehicle::allowed_move(), ASL_CLOSED, ASL_NONE, pathfinding_settings::avoid_rough_terrain, pathfinding_settings::avoid_sharp, pathfinding_settings::avoid_traps, bash(), bash_rating_internal(), pathfinding_settings::bash_strength, pathfinding_settings::climb_cost, clip_to_bounds(), vehicle::cpart(), debugmsg, detail::digits::done, flat_index(), furniture, maptile::get_furn_t(), get_pathfinding_cache_ref(), maptile::get_ter_t(), maptile::get_trap_t(), has_flag(), has_zlevels(), hp, vehicle_part::hp(), inbounds(), is_disjoint(), is_outside(), line_to(), maptile_at_internal(), pathfinding_settings::max_dist, pathfinding_settings::max_length, move_cost_internal(), vpart_position::obstacle_at_part(), vehicle::part_flag(), PF_CLIMBABLE, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, cata::hash64_detail::ret, rl_dist(), route(), terrain, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, vehicle::tripoint_to_mount(), valid_move(), veh_at_internal(), VPFLAG_OPENABLE, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), Character::can_mount(), npc::go_to_omt_destination(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route(), route_adjacent(), activity_handlers::travel_do_turn(), game::try_get_left_click_action(), and npc::update_path().

◆ save()

void map::save ( )

Add currently loaded submaps (in grid) to the mapbuffer.

They will than be stored by that class and can be loaded from that class. This can be called several times, the mapbuffer takes care of adding the same submap several times. It should only be called after the map has been loaded. Submaps that have been loaded from the mapbuffer (and not generated) are already stored in the mapbuffer. TODO: determine if this is really needed? Submaps are already in the mapbuffer if they have been loaded from disc and the are added by map::generate, too. So when do they not appear in the mapbuffer?

Definition at line 6705 of file map.cpp.

6706{
6707 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6708 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6709 if( zlevels ) {
6710 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
6711 saven( tripoint( gridx, gridy, gridz ) );
6712 }
6713 } else {
6714 saven( tripoint( gridx, gridy, abs_sub.z ) );
6715 }
6716 }
6717 }
6718}

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, saven(), tripoint::z, and zlevels.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), defense_game::init_map(), mission_start::kill_horde_master(), talk_function::loot_building(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), game::save_maps(), and debug_menu::spawn_nested_mapgen().

◆ saven()

void map::saven ( const tripoint grid)
protected

Definition at line 7048 of file map.cpp.

7049{
7050 dbg( DL::Debug ) << "map::saven( world=" << abs_sub << ", grid=" << grid << " )";
7051 const int gridn = get_nonant( grid );
7052 submap *submap_to_save = getsubmap( gridn );
7053 if( submap_to_save == nullptr || submap_to_save->get_ter( point_zero ) == t_null ) {
7054 // This is a serious error and should be signaled as soon as possible
7055 debugmsg( "map::saven grid (%s) %s!", grid.to_string(),
7056 submap_to_save == nullptr ? "null" : "uninitialized" );
7057 return;
7058 }
7059
7060 const tripoint abs = abs_sub.xy() + grid;
7061
7062 if( !zlevels && grid.z != abs_sub.z ) {
7063 debugmsg( "Tried to save submap (%d,%d,%d) as (%d,%d,%d), which isn't supported in non-z-level builds",
7064 abs.x, abs.y, abs_sub.z, abs.x, abs.y, grid.z );
7065 }
7066
7067 dbg( DL::Debug ) << "map::saven abs: " << abs << " gridn: " << gridn;
7068
7069 // An edge case: restock_fruits relies on last_touched, so we must call it before save
7070 if( season_of_year( calendar::turn ) != season_of_year( submap_to_save->last_touched ) ) {
7071 const time_duration time_since_last_actualize = calendar::turn - submap_to_save->last_touched;
7072 for( int x = 0; x < SEEX; x++ ) {
7073 for( int y = 0; y < SEEY; y++ ) {
7074 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7075 restock_fruits( pnt, time_since_last_actualize );
7076 }
7077 }
7078 }
7079
7080 submap_to_save->last_touched = calendar::turn;
7081 MAPBUFFER.add_submap( abs, submap_to_save );
7082}
bool add_submap(const tripoint &p, std::unique_ptr< submap > &sm)
Add a new submap to the buffer.
Definition: mapbuffer.cpp:50
@ Debug
Debug information (default: disabled).

References abs_sub, mapbuffer::add_submap(), dbg, Debug, debugmsg, get_nonant(), submap::get_ter(), getsubmap(), grid, submap::last_touched, MAPBUFFER, point_zero, restock_fruits(), season_of_year(), SEEX, SEEY, sm_to_ms_copy(), t_null, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by generate(), and save().

◆ scent_blockers()

void map::scent_blockers ( std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &  scent_transfer,
point  min,
point  max 
)

Build the map of scent-resistant tiles.

Should be way faster than if done in game.cpp using public map functions.

Definition at line 8672 of file map.cpp.

8674{
8675 auto reduce = TFLAG_REDUCE_SCENT;
8676 auto block = TFLAG_NO_SCENT;
8677 auto fill_values = [&]( const tripoint & gp, const submap * sm, point lp ) {
8678 // We need to generate the x/y coordinates, because we can't get them "for free"
8679 const point p = lp + sm_to_ms_copy( gp.xy() );
8680 if( sm->get_ter( lp ).obj().has_flag( block ) ) {
8681 scent_transfer[p.x][p.y] = 0;
8682 } else if( sm->get_ter( lp ).obj().has_flag( reduce ) ||
8683 sm->get_furn( lp ).obj().has_flag( reduce ) ) {
8684 scent_transfer[p.x][p.y] = 1;
8685 } else {
8686 scent_transfer[p.x][p.y] = 5;
8687 }
8688
8689 return ITER_CONTINUE;
8690 };
8691
8692 function_over( tripoint( min, abs_sub.z ), tripoint( max, abs_sub.z ), fill_values );
8693
8694 const inclusive_rectangle<point> local_bounds( min, max );
8695
8696 // Now vehicles
8697
8698 auto vehs = get_vehicles();
8699 for( auto &wrapped_veh : vehs ) {
8700 vehicle &veh = *( wrapped_veh.v );
8701 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OBSTACLE ) ) {
8702 const tripoint part_pos = vp.pos();
8703 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8704 scent_transfer[part_pos.x][part_pos.y] = 1;
8705 }
8706 }
8707
8708 // Doors, but only the closed ones
8709 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OPENABLE ) ) {
8710 if( vp.part().open ) {
8711 continue;
8712 }
8713
8714 const tripoint part_pos = vp.pos();
8715 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8716 scent_transfer[part_pos.x][part_pos.y] = 1;
8717 }
8718 }
8719 }
8720}
void function_over(const tripoint &start, const tripoint &end, Functor fun) const
Runs a functor over given submaps over submaps in the area, getting next submap only when the current...
Definition: map.cpp:8618
@ TFLAG_REDUCE_SCENT
Definition: mapdata.h:278
@ TFLAG_NO_SCENT
Definition: mapdata.h:284
@ VPFLAG_OBSTACLE
Definition: veh_type.h:42

References abs_sub, inclusive_rectangle< Point, >::contains(), function_over(), vehicle::get_any_parts(), get_vehicles(), ITER_CONTINUE, coords::sm, sm_to_ms_copy(), TFLAG_NO_SCENT, TFLAG_REDUCE_SCENT, VPFLAG_OBSTACLE, VPFLAG_OPENABLE, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by scent_map::update().

◆ sees() [1/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range 
) const

Returns whether F sees T with a view range of range.

Definition at line 6240 of file map.cpp.

6241{
6242 int dummy = 0;
6243 return sees( F, T, range, dummy );
6244}

References sees().

Referenced by apply_ammo_effects(), find_clear_path(), mattack::flame(), explosion_handler::explosion_funcs::flashbang(), get_heat_radiation(), projectile_attack(), Creature::sees(), sees(), Character::sees_with_infrared(), shake_vehicle(), shoot(), spawn_monsters_submap_group(), and vehicle_selector::vehicle_selector().

◆ sees() [2/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range,
int &  bresenham_slope 
) const
private

Don't expose the slope adjust outside map functions.

This one is internal-only, we don't want to expose the slope tweaking ickiness outside the map class.

Parameters
FThing doing the seeing
TThing being seen
rangeVision range of F
bresenham_slopeIndicates the start offset of Bresenham line used to connect the two points, and may subsequently be used to form a path between them. Set to zero if the function returns false.

Definition at line 6249 of file map.cpp.

6251{
6252 if( ( range >= 0 && range < rl_dist( F, T ) ) ||
6253 !inbounds( T ) ) {
6254 bresenham_slope = 0;
6255 return false; // Out of range!
6256 }
6257 // Cannonicalize the order of the tripoints so the cache is reflexive.
6258 const tripoint &min = F < T ? F : T;
6259 const tripoint &max = !( F < T ) ? F : T;
6260 // A little gross, just pack the values into a point.
6261 const point key(
6262 min.x << 16 | min.y << 8 | ( min.z + OVERMAP_DEPTH ),
6263 max.x << 16 | max.y << 8 | ( max.z + OVERMAP_DEPTH )
6264 );
6265 char cached = skew_vision_cache.get( key, -1 );
6266 if( cached >= 0 ) {
6267 return cached > 0;
6268 }
6269
6270 bool visible = true;
6271
6272 // Ugly `if` for now
6273 if( !fov_3d || F.z == T.z ) {
6274
6275 point last_point = F.xy();
6276 bresenham( F.xy(), T.xy(), bresenham_slope,
6277 [this, &visible, &T, &last_point]( point new_point ) {
6278 // Exit before checking the last square, it's still visible even if opaque.
6279 if( new_point.x == T.x && new_point.y == T.y ) {
6280 return false;
6281 }
6282 if( !this->is_transparent( tripoint( new_point, T.z ) ) ||
6283 obscured_by_vehicle_rotation( tripoint( last_point, T.z ), tripoint( new_point, T.z ) ) ) {
6284 visible = false;
6285 return false;
6286 }
6287 last_point = new_point;
6288 return true;
6289 } );
6290 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6291 return visible;
6292 }
6293
6294 tripoint last_point = F;
6295 bresenham( F, T, bresenham_slope, 0,
6296 [this, &visible, &T, &last_point]( const tripoint & new_point ) {
6297 // Exit before checking the last square if it's not a vertical transition,
6298 // it's still visible even if opaque.
6299 if( new_point == T && last_point.z == T.z ) {
6300 return false;
6301 }
6302
6303 // TODO: Allow transparent floors (and cache them!)
6304 if( new_point.z == last_point.z ) {
6305 if( !this->is_transparent( new_point ) || obscured_by_vehicle_rotation( last_point, new_point ) ) {
6306 visible = false;
6307 return false;
6308 }
6309 } else {
6310 const int max_z = std::max( new_point.z, last_point.z );
6311 if( ( has_floor_or_support( {new_point.xy(), max_z} ) ||
6312 !is_transparent( {new_point.xy(), last_point.z} ) ) &&
6313 ( has_floor_or_support( {last_point.xy(), max_z} ) ||
6314 !is_transparent( {last_point.xy(), new_point.z} ) ) ) {
6315 visible = false;
6316 return false;
6317 }
6318 }
6319
6320 last_point = new_point;
6321 return true;
6322 } );
6323 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6324 return visible;
6325}

References bresenham(), fov_3d, inbounds(), obscured_by_vehicle_rotation(), OVERMAP_DEPTH, rl_dist(), skew_vision_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

◆ sees_some_items() [1/2]

bool map::sees_some_items ( const tripoint p,
const Creature who 
) const

Check if creature can see some items at p.

Includes:

  • check for items at this location (has_items(p))
  • check for SEALED flag (sealed furniture/terrain makes items not visible under any circumstances).
  • check for CONTAINER flag (makes items only visible when the creature is at p or at an adjacent square).

Definition at line 4833 of file map.cpp.

4834{
4835 // Can only see items if there are any items.
4836 return has_items( p ) && could_see_items( p, who.pos() );
4837}

References could_see_items(), has_items(), and Creature::pos().

Referenced by game::butcher(), editmap::draw_main_ui_overlay(), draw_maptile(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), vehicle::interact_with(), game::print_items_info(), and npc::see_item_say_smth().

◆ sees_some_items() [2/2]

bool map::sees_some_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4839 of file map.cpp.

4840{
4841 return has_items( p ) && could_see_items( p, from );
4842}

References could_see_items(), and has_items().

◆ set() [1/2]

void map::set ( const tripoint p,
const ter_id new_terrain,
const furn_id new_furniture 
)

Definition at line 1383 of file map.cpp.

1384{
1385 furn_set( p, new_furniture );
1386 ter_set( p, new_terrain );
1387}

References furn_set(), and ter_set().

Referenced by farm_action(), talk_function::field_plant(), mapgen_function_json_base::formatted_set_incredibly_simple(), and activity_handlers::plant_seed_finish().

◆ set() [2/2]

void map::set ( point  p,
const ter_id new_terrain,
const furn_id new_furniture 
)
inline

Definition at line 774 of file map.h.

774 {
775 furn_set( p, new_furniture );
776 ter_set( p, new_terrain );
777 }

References furn_set(), and ter_set().

◆ set_abs_sub()

void map::set_abs_sub ( const tripoint p)
protected

Sets abs_sub, see there.

Uses the same coordinate system as abs_sub.

Definition at line 8398 of file map.cpp.

8399{
8400 abs_sub = p;
8401}

References abs_sub.

Referenced by fake_map::fake_map(), generate(), load(), shift(), and vertical_shift().

◆ set_field_age()

time_duration map::set_field_age ( const tripoint p,
const field_type_id type,
const time_duration age,
bool  isoffset = false 
)

Set age of field entry at point.

Parameters
pLocation of field
typeID of field
ageNew age of specified field
isoffsetIf true, the given age value is added to the existing value, if false, the existing age is ignored and overridden.
Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5437 of file map.cpp.

5439{
5440 if( field_entry *const field_ptr = get_field( p, type ) ) {
5441 return field_ptr->set_field_age( ( isoffset ? field_ptr->get_field_age() : 0_turns ) + age );
5442 }
5443 return -1_turns;
5444}

References get_field(), and type.

Referenced by game::grabbed_furn_move(), mod_field_age(), and game::walk_move().

◆ set_field_intensity()

int map::set_field_intensity ( const tripoint p,
const field_type_id type,
int  new_intensity,
bool  isoffset = false 
)

Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Parameters
pLocation of field
typeID of field
new_intensityNew intensity of field
isoffsetIf true, the given new_intensity value is added to the existing value, if false, the existing intensity is ignored and overridden.
Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5450 of file map.cpp.

5453{
5454 field_entry *field_ptr = get_field( p, type );
5455 if( field_ptr != nullptr ) {
5456 int adj = ( isoffset ? field_ptr->get_field_intensity() : 0 ) + new_intensity;
5457 if( adj > 0 ) {
5458 field_ptr->set_field_intensity( adj );
5459 return adj;
5460 } else {
5461 remove_field( p, type );
5462 return 0;
5463 }
5464 } else if( 0 + new_intensity > 0 ) {
5465 return add_field( p, type, new_intensity ) ? new_intensity : 0;
5466 }
5467
5468 return 0;
5469}

References add_field(), get_field(), field_entry::get_field_intensity(), remove_field(), field_entry::set_field_intensity(), and type.

Referenced by editmap::edit_fld(), game::grabbed_furn_move(), mod_field_intensity(), spell_move(), and game::walk_move().

◆ set_floor_cache_dirty()

void map::set_floor_cache_dirty ( const int  zlev)

◆ set_graffiti()

void map::set_graffiti ( const tripoint p,
const std::string &  contents 
)

Definition at line 7919 of file map.cpp.

7920{
7921 if( !inbounds( p ) ) {
7922 return;
7923 }
7924 point l;
7925 submap *const current_submap = get_submap_at( p, l );
7926 current_submap->set_graffiti( l, contents );
7927}
void set_graffiti(point p, const std::string &new_graffiti)
Definition: submap.cpp:132

References get_submap_at(), inbounds(), and submap::set_graffiti().

Referenced by jmapgen_graffiti::apply().

◆ set_memory_seen_cache_dirty()

void map::set_memory_seen_cache_dirty ( const tripoint p)

Definition at line 8952 of file map.cpp.

8953{
8954 const int offset = p.x + p.y * MAPSIZE_Y;
8955 if( offset >= 0 && offset < MAPSIZE_X * MAPSIZE_Y ) {
8956 get_cache( p.z ).map_memory_seen_cache.reset( offset );
8957 }
8958}

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_X, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by vehicle::damage_direct(), furn_set(), vehicle::stop(), and ter_set().

◆ set_outside_cache_dirty()

void map::set_outside_cache_dirty ( const int  zlev)

◆ set_pathfinding_cache_dirty()

void map::set_pathfinding_cache_dirty ( int  zlev)

◆ set_radiation() [1/2]

void map::set_radiation ( const tripoint p,
int  value 
)

Definition at line 4143 of file map.cpp.

4144{
4145 if( !inbounds( p ) ) {
4146 return;
4147 }
4148
4149 point l;
4150 submap *const current_submap = get_submap_at( p, l );
4151
4152 current_submap->set_radiation( l, value );
4153}

References get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by jmapgen_setmap::apply(), create_anomaly(), draw_lab(), mapgen_crater(), mapgen_null(), mapgen_test(), and set_radiation().

◆ set_radiation() [2/2]

void map::set_radiation ( point  p,
const int  value 
)
inline

Definition at line 1156 of file map.h.

1156 {
1157 set_radiation( tripoint( p, abs_sub.z ), value );
1158 }

References abs_sub, set_radiation(), and tripoint::z.

◆ set_seen_cache_dirty() [1/2]

void map::set_seen_cache_dirty ( const int  zlevel)

Definition at line 242 of file map.cpp.

243{
244 if( inbounds_z( zlevel ) ) {
245 level_cache &cache = get_cache( zlevel );
246 cache.seen_cache_dirty = true;
247 }
248}

References get_cache(), inbounds_z(), and level_cache::seen_cache_dirty.

◆ set_seen_cache_dirty() [2/2]

void map::set_seen_cache_dirty ( const tripoint  change_location)

Definition at line 207 of file map.cpp.

208{
209 if( inbounds( change_location ) ) {
210 level_cache &cache = get_cache( change_location.z );
211 if( cache.seen_cache_dirty ) {
212 return;
213 }
214 if( cache.seen_cache[change_location.x][change_location.y] != 0.0 ||
215 cache.camera_cache[change_location.x][change_location.y] != 0.0 ) {
216 cache.seen_cache_dirty = true;
217 }
218 }
219}

References level_cache::camera_cache, get_cache(), inbounds(), level_cache::seen_cache, level_cache::seen_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), trapfunc::map_regen(), vehicle::merge_rackable_vehicle(), vehicle::open_or_close(), process_fields_in_submap(), remove_field(), avatar::set_movement_mode(), DefaultRemovePartHandler::set_transparency_cache_dirty(), vehicle::split_vehicles(), ter_set(), and weather_manager::update_weather().

◆ set_signage()

void map::set_signage ( const tripoint p,
const std::string &  message 
) const

Definition at line 4108 of file map.cpp.

4109{
4110 if( !inbounds( p ) ) {
4111 return;
4112 }
4113
4114 point l;
4115 submap *const current_submap = get_submap_at( p, l );
4116
4117 current_submap->set_signage( l, message );
4118}
void set_signage(point p, const std::string &s)
Definition: submap.cpp:172
std::string message
Definition: mapgen.cpp:411

References get_submap_at(), inbounds(), mapgen_defer::message, and submap::set_signage().

Referenced by jmapgen_sign::apply(), MapExtras::mx_grave(), MapExtras::mx_minefield(), and iexamine::sign().

◆ set_suspension_cache_dirty()

void map::set_suspension_cache_dirty ( const int  zlev)

Definition at line 228 of file map.cpp.

229{
230 if( inbounds_z( zlev ) ) {
231 get_cache( zlev ).suspension_cache_dirty = true;
232 }
233}

References get_cache(), inbounds_z(), and level_cache::suspension_cache_dirty.

Referenced by loadn(), editmap::mapgen_preview(), and ter_set().

◆ set_temperature() [1/2]

void map::set_temperature ( const tripoint p,
int  temperature 
)

Definition at line 4177 of file map.cpp.

4178{
4179 if( !inbounds( p ) ) {
4180 return;
4181 }
4182
4183 get_submap_at( p )->set_temperature( new_temperature );
4184}
void set_temperature(int new_temperature)
Definition: submap.h:169

References get_submap_at(), inbounds(), and submap::set_temperature().

Referenced by draw_lab(), and set_temperature().

◆ set_temperature() [2/2]

void map::set_temperature ( point  p,
int  new_temperature 
)
inline

Definition at line 1173 of file map.h.

1173 {
1174 set_temperature( tripoint( p, abs_sub.z ), new_temperature );
1175 }

References abs_sub, set_temperature(), and tripoint::z.

◆ set_transparency_cache_dirty() [1/2]

void map::set_transparency_cache_dirty ( const int  zlev)

◆ set_transparency_cache_dirty() [2/2]

void map::set_transparency_cache_dirty ( const tripoint p)

Definition at line 250 of file map.cpp.

251{
252 if( inbounds( p ) ) {
253 const tripoint smp = ms_to_sm_copy( p );
254 get_cache( smp.z ).transparency_cache_dirty.set( smp.x * MAPSIZE + smp.y );
255 }
256}

References get_cache(), inbounds(), MAPSIZE, ms_to_sm_copy(), level_cache::transparency_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

◆ setsubmap()

void map::setsubmap ( size_t  grididx,
submap smap 
)
protected

Set the submap pointer in grid at the give index.

This is the inverse of getsubmap, any existing pointer is overwritten. The index must be valid. The given submap pointer must not be null.

Definition at line 8417 of file map.cpp.

8418{
8419 if( grididx >= grid.size() ) {
8420 debugmsg( "Tried to access invalid grid index %d", grididx );
8421 return;
8422 } else if( smap == nullptr ) {
8423 debugmsg( "Tried to set NULL submap pointer at index %d", grididx );
8424 return;
8425 }
8426 grid[grididx] = smap;
8427}

References debugmsg, and grid.

Referenced by copy_grid(), fake_map::fake_map(), generate(), and loadn().

◆ shake_vehicle()

units::angle map::shake_vehicle ( vehicle veh,
int  velocity_before,
units::angle  direction 
)
Strength reduces chance of being thrown from your seat when not wearing a seatbelt Strength reduces chance of being thrown from your seat when not wearing a seatbelt Dexterity reduces chance of losing control of vehicle when shaken Driving reduces chance of losing control of vehicle when shaken Strength reduces distance thrown from seat in a vehicle impact

Definition at line 1650 of file vehicle_move.cpp.

1652{
1653 const int d_vel = std::abs( veh.velocity - velocity_before ) / 100;
1654
1655 std::vector<rider_data> riders = veh.get_riders();
1656
1657 units::angle coll_turn = 0_degrees;
1658 for( const rider_data &r : riders ) {
1659 const int ps = r.prt;
1660 Creature *rider = r.psg;
1661 if( rider == nullptr ) {
1662 debugmsg( "throw passenger: empty passenger at part %d", ps );
1663 continue;
1664 }
1665
1666 const tripoint part_pos = veh.global_part_pos3( ps );
1667 if( rider->pos() != part_pos ) {
1668 debugmsg( "throw passenger: passenger at %d,%d,%d, part at %d,%d,%d",
1669 rider->posx(), rider->posy(), rider->posz(),
1670 part_pos.x, part_pos.y, part_pos.z );
1672 continue;
1673 }
1674
1675 player *psg = dynamic_cast<player *>( rider );
1676 monster *pet = dynamic_cast<monster *>( rider );
1677
1678 bool throw_from_seat = false;
1679 int move_resist = 1;
1680 if( psg ) {
1681 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1682 move_resist = psg->str_cur * 150 + 500;
1683 } else {
1684 int pet_resist = 0;
1685 if( pet != nullptr ) {
1686 pet_resist = static_cast<int>( to_kilogram( pet->get_weight() ) * 200 );
1687 }
1688 move_resist = std::max( 100, pet_resist );
1689 }
1690 if( veh.part_with_feature( ps, VPFLAG_SEATBELT, true ) == -1 ) {
1691 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1692 throw_from_seat = d_vel * rng( 80, 120 ) > move_resist;
1693 }
1694
1695 // Damage passengers if d_vel is too high
1696 if( !throw_from_seat && ( 10 * d_vel ) > 6 * rng( 50, 100 ) ) {
1697 const int dmg = d_vel * rng( 70, 100 ) / 400;
1698 if( psg ) {
1699 psg->hurtall( dmg, nullptr );
1701 _( "You take %d damage by the power of the impact!" ),
1702 _( "<npcname> takes %d damage by the power of the "
1703 "impact!" ), dmg );
1704 } else {
1705 pet->apply_damage( nullptr, bodypart_id( "torso" ), dmg );
1706 }
1707 }
1708
1709 if( psg && veh.player_in_control( *psg ) ) {
1710 const int lose_ctrl_roll = rng( 0, d_vel );
1711 ///\EFFECT_DEX reduces chance of losing control of vehicle when shaken
1712
1713 ///\EFFECT_DRIVING reduces chance of losing control of vehicle when shaken
1714 if( lose_ctrl_roll > psg->dex_cur * 2 + psg->get_skill_level( skill_driving ) * 3 ) {
1716 _( "You lose control of the %s." ),
1717 _( "<npcname> loses control of the %s." ), veh.name );
1718 int turn_amount = rng( 1, 3 ) * std::sqrt( std::abs( veh.velocity ) ) / 30;
1719 if( turn_amount < 1 ) {
1720 turn_amount = 1;
1721 }
1722 units::angle turn_angle = std::min( turn_amount * 15_degrees, 120_degrees );
1723 coll_turn = one_in( 2 ) ? turn_angle : -turn_angle;
1724 }
1725 }
1726
1727 if( throw_from_seat ) {
1728 if( psg ) {
1730 _( "You are hurled from the %s's seat by "
1731 "the power of the impact!" ),
1732 _( "<npcname> is hurled from the %s's seat by "
1733 "the power of the impact!" ), veh.name );
1734 unboard_vehicle( part_pos );
1735 } else if( get_player_character().sees( part_pos ) ) {
1736 add_msg( m_bad, _( "The %s is hurled from %s's by the power of the impact!" ),
1737 pet->disp_name(), veh.name );
1738 }
1739 ///\EFFECT_STR reduces distance thrown from seat in a vehicle impact
1740 g->fling_creature( rider, direction + rng_float( -30_degrees, 30_degrees ),
1741 std::max( 10, d_vel - move_resist / 100 ) );
1742 }
1743 }
1744
1745 return coll_turn;
1746}
int dex_cur
Definition: character.h:265
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3332
units::mass get_weight() const override
Definition: monster.cpp:2700
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:537
@ VPFLAG_SEATBELT
Definition: veh_type.h:45
static const skill_id skill_driving("driving")

References _, add_msg(), player::add_msg_player_or_npc(), monster::apply_damage(), debugmsg, Character::dex_cur, monster::disp_name(), g, get_player_character(), vehicle::get_riders(), Character::get_skill_level(), monster::get_weight(), vehicle::global_part_pos3(), Character::hurtall(), m_bad, m_warning, vehicle::name, one_in(), vehicle::part(), vehicle::part_with_feature(), vehicle_part::passenger_flag, vehicle::player_in_control(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::remove_flag(), rng(), rng_float(), sees(), skill_driving, Character::str_cur, units::to_kilogram(), unboard_vehicle(), vehicle::velocity, VPFLAG_SEATBELT, tripoint::x, tripoint::y, and tripoint::z.

Referenced by move_vehicle().

◆ shift()

void map::shift ( point  s)

Shift the map along the vector s.

This is like loading the map with coordinates derived from the current position of the map (abs_sub) plus the shift vector. Note: the map must have been loaded before this can be called.

Definition at line 6877 of file map.cpp.

6878{
6879 // Special case of 0-shift; refresh the map
6880 if( sp == point_zero ) {
6881 return; // Skip this?
6882 }
6883
6884 if( std::abs( sp.x ) > 1 || std::abs( sp.y ) > 1 ) {
6885 debugmsg( "map::shift called with a shift of more than one submap" );
6886 }
6887
6888 const tripoint abs = get_abs_sub();
6889
6890 set_abs_sub( abs + sp );
6891
6892 // if player is in vehicle, (s)he must be shifted with vehicle too
6893 if( g->u.in_vehicle ) {
6894 g->u.setx( g->u.posx() - sp.x * SEEX );
6895 g->u.sety( g->u.posy() - sp.y * SEEY );
6896 }
6897
6898 g->shift_destination_preview( point( -sp.x * SEEX, -sp.y * SEEY ) );
6899
6900 shift_traps( tripoint( sp, 0 ) );
6901
6902 vehicle *remoteveh = g->remoteveh();
6903
6904 const int zmin = zlevels ? -OVERMAP_DEPTH : abs.z;
6905 const int zmax = zlevels ? OVERMAP_HEIGHT : abs.z;
6906 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6907 for( vehicle *veh : get_cache( gridz ).vehicle_list ) {
6908 veh->zones_dirty = true;
6909 }
6910 }
6911
6912 constexpr half_open_rectangle<point> boundaries_2d( point_zero, point( MAPSIZE_Y, MAPSIZE_X ) );
6913 const point shift_offset_pt( -sp.x * SEEX, -sp.y * SEEY );
6914
6915 // Clear vehicle list and rebuild after shift
6917 // Shift the map sx submaps to the right and sy submaps down.
6918 // sx and sy should never be bigger than +/-1.
6919 // absx and absy are our position in the world, for saving/loading purposes.
6920 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6921 clear_vehicle_list( gridz );
6922 shift_bitset_cache<MAPSIZE_X, SEEX>( get_cache( gridz ).map_memory_seen_cache, sp );
6923 shift_bitset_cache<MAPSIZE, 1>( get_cache( gridz ).field_cache, sp );
6924 if( sp.x >= 0 ) {
6925 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6926 if( sp.y >= 0 ) {
6927 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6928 if( ( sp.x > 0 && gridx == 0 ) || ( sp.y > 0 && gridy == 0 ) ) {
6929 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6930 }
6931 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y < my_MAPSIZE ) {
6932 copy_grid( tripoint( gridx, gridy, gridz ),
6933 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6934 update_vehicle_list( get_submap_at_grid( {gridx, gridy, gridz} ), gridz );
6935 } else {
6936 loadn( tripoint( gridx, gridy, gridz ), true );
6937 }
6938 }
6939 } else { // sy < 0; work through it backwards
6940 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6941 if( ( sp.x > 0 && gridx == 0 ) || gridy == my_MAPSIZE - 1 ) {
6942 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6943 }
6944 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y >= 0 ) {
6945 copy_grid( tripoint( gridx, gridy, gridz ),
6946 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6947 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6948 } else {
6949 loadn( tripoint( gridx, gridy, gridz ), true );
6950 }
6951 }
6952 }
6953 }
6954 } else { // sx < 0; work through it backwards
6955 for( int gridx = my_MAPSIZE - 1; gridx >= 0; gridx-- ) {
6956 if( sp.y >= 0 ) {
6957 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6958 if( gridx == my_MAPSIZE - 1 || ( sp.y > 0 && gridy == 0 ) ) {
6959 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6960 }
6961 if( gridx + sp.x >= 0 && gridy + sp.y < my_MAPSIZE ) {
6962 copy_grid( tripoint( gridx, gridy, gridz ),
6963 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6964 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6965 } else {
6966 loadn( tripoint( gridx, gridy, gridz ), true );
6967 }
6968 }
6969 } else { // sy < 0; work through it backwards
6970 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6971 if( gridx == my_MAPSIZE - 1 || gridy == my_MAPSIZE - 1 ) {
6972 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6973 }
6974 if( gridx + sp.x >= 0 && gridy + sp.y >= 0 ) {
6975 copy_grid( tripoint( gridx, gridy, gridz ),
6976 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6977 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6978 } else {
6979 loadn( tripoint( gridx, gridy, gridz ), true );
6980 }
6981 }
6982 }
6983 }
6984 }
6985 }
6986 if( zlevels ) {
6987 //Go through the generated maps and fill in the roofs
6988 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6989 if( sp.x > 0 ) {
6990 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6991 add_roofs( {my_MAPSIZE - 1, gridy, gridz} );
6992 }
6993 } else if( sp.x < 0 ) {
6994 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6995 add_roofs( {0, gridy, gridz} );
6996 }
6997 }
6998
6999 if( sp.y > 0 ) {
7000 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
7001 add_roofs( {gridx, my_MAPSIZE - 1, gridz} );
7002 }
7003 } else if( sp.y < 0 ) {
7004 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
7005 add_roofs( {gridx, 0, gridz} );
7006 }
7007 }
7008 }
7009 }
7010
7012
7013 g->setremoteveh( remoteveh );
7014
7015 if( !support_cache_dirty.empty() ) {
7016 shift_tripoint_set( support_cache_dirty, shift_offset_pt, boundaries_2d );
7017 }
7018}
void copy_grid(const tripoint &to, const tripoint &from)
Definition: map.cpp:7619
void shift_traps(const tripoint &shift)
As part of the map shifting, this shifts the trap locations stored in traplocs.
Definition: map.cpp:6745
template void shift_bitset_cache< MAPSIZE_X, SEEX >(std::bitset< MAPSIZE_X *MAPSIZE_X > &cache, point s)
static void shift_tripoint_set(std::set< tripoint > &set, point offset, const half_open_rectangle< point > &boundaries)
Definition: map.cpp:6804
template void shift_bitset_cache< MAPSIZE, 1 >(std::bitset< MAPSIZE *MAPSIZE > &cache, point s)
int remoteveh(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:8262

References add_roofs(), clear_vehicle_cache(), clear_vehicle_list(), copy_grid(), debugmsg, g, get_abs_sub(), get_cache(), get_submap_at_grid(), loadn(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, iuse::remoteveh(), reset_vehicle_cache(), SEEX, SEEY, set_abs_sub(), shift_bitset_cache< MAPSIZE, 1 >(), shift_bitset_cache< MAPSIZE_X, SEEX >(), shift_traps(), shift_tripoint_set(), submaps_with_active_items, support_cache_dirty, update_vehicle_list(), point::x, point::y, and zlevels.

Referenced by shift_traps(), and game::update_map().

◆ shift_traps()

void map::shift_traps ( const tripoint shift)
protected

As part of the map shifting, this shifts the trap locations stored in traplocs.

Parameters
shiftThe amount shifting in submap, the same as go into shift.

Definition at line 6745 of file map.cpp.

6746{
6747 // Offset needs to have sign opposite to shift direction
6748 const tripoint offset( -shift.x * SEEX, -shift.y * SEEY, -shift.z );
6749 for( auto iter = field_furn_locs.begin(); iter != field_furn_locs.end(); ) {
6750 tripoint &pos = *iter;
6751 pos += offset;
6752 if( inbounds( pos ) ) {
6753 ++iter;
6754 } else {
6755 iter = field_furn_locs.erase( iter );
6756 }
6757 }
6758 for( auto &traps : traplocs ) {
6759 for( auto iter = traps.begin(); iter != traps.end(); ) {
6760 tripoint &pos = *iter;
6761 pos += offset;
6762 if( inbounds( pos ) ) {
6763 ++iter;
6764 } else {
6765 // Theoretical enhancement: if this is not the last entry of the vector,
6766 // move the last entry into pos and remove the last entry instead of iter.
6767 // This would avoid moving all the remaining entries.
6768 iter = traps.erase( iter );
6769 }
6770 }
6771 }
6772}
void shift(point s)
Shift the map along the vector s.
Definition: map.cpp:6877

References field_furn_locs, inbounds(), SEEX, SEEY, shift(), and traplocs.

Referenced by shift().

◆ shift_vehicle_z()

void map::shift_vehicle_z ( vehicle veh,
int  z_shift 
)

Definition at line 6831 of file map.cpp.

6832{
6833
6834 tripoint src = veh.global_pos3();
6835 tripoint dst = src + tripoint_above * z_shift;
6836
6837 submap *src_submap = get_submap_at( src );
6838 submap *dst_submap = get_submap_at( dst );
6839
6840 int our_i = -1;
6841 for( size_t i = 0; i < src_submap->vehicles.size(); i++ ) {
6842 if( src_submap->vehicles[i].get() == &veh ) {
6843 our_i = i;
6844 break;
6845 }
6846 }
6847
6848 if( our_i == -1 ) {
6849 debugmsg( "shift_vehicle [%s] failed could not find vehicle", veh.name );
6850 return;
6851 }
6852
6853 for( auto &prt : veh.get_all_parts() ) {
6854 prt.part().precalc[0].z -= z_shift;
6855 }
6856
6857 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
6858 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
6859 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
6860 src_submap->vehicles.erase( src_submap_veh_it );
6861 dst_submap->is_uniform = false;
6863
6864 update_vehicle_list( dst_submap, dst.z );
6865
6866 level_cache &ch = get_cache( src.z );
6867 for( const vehicle *elem : ch.vehicle_list ) {
6868 if( elem == &veh ) {
6869 ch.vehicle_list.erase( &veh );
6870 ch.zone_vehicles.erase( &veh );
6871 break;
6872 }
6873 }
6874
6875}

References debugmsg, vehicle::get_all_parts(), get_cache(), get_submap_at(), vehicle::global_pos3(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), vehicle::name, SEEX, SEEY, vehicle::set_submap_moved(), tripoint_above, update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by vehicle::shift_zlevel().

◆ shoot()

void map::shoot ( const tripoint p,
projectile proj,
bool  hit_items 
)

Definition at line 3820 of file map.cpp.

3821{
3822 float initial_damage = 0.0;
3823 for( const damage_unit &dam : proj.impact ) {
3824 initial_damage += dam.amount * dam.damage_multiplier;
3825 initial_damage += dam.res_pen;
3826 }
3827 if( initial_damage < 0 ) {
3828 return;
3829 }
3830
3831 float dam = initial_damage;
3832
3833 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3834 sounds::sound( p, 30, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment",
3835 "alarm" );
3836 const tripoint abs = ms_to_sm_copy( getabs( p ) );
3837 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0, abs );
3838 }
3839
3840 const bool inc = proj.has_effect( ammo_effect_INCENDIARY ) ||
3841 proj.impact.type_damage( DT_HEAT ) > 0;
3842 if( const optional_vpart_position vp = veh_at( p ) ) {
3843 dam = vp->vehicle().damage( vp->part_index(), dam, inc ? DT_HEAT : DT_STAB, hit_items );
3844 }
3845
3846 ter_id terrain = ter( p );
3847 ter_t ter = terrain.obj();
3848
3849 if( ter.bash.ranged ) {
3850 const ranged_bash_info &ri = *ter.bash.ranged;
3851 if( !hit_items && !check( ri.block_unaimed_chance ) ) {
3852 // Nothing, it's a miss
3853 } else if( ri.reduction_laser && proj.has_effect( ammo_effect_LASER ) ) {
3854 dam -= rng( ri.reduction_laser->min, ri.reduction_laser->max );
3855 } else {
3856 dam -= rng( ri.reduction.min, ri.reduction.max );
3857 if( dam > ri.destroy_threshold ) {
3858 bash_params params{0, false, true, hit_items, 1.0, false};
3859 bash_ter_success( p, params );
3860 }
3861 if( dam <= 0 && is_transparent( p ) && get_avatar().sees( p ) ) {
3862 add_msg( _( "The shot is stopped by the %s!" ), tername( p ) );
3863 }
3864 if( ri.flammable && inc ) {
3865 add_field( p, fd_fire, 1 );
3866 }
3867 }
3868 } else if( impassable( p ) && !is_transparent( p ) ) {
3869 bash( p, dam, false );
3870 // TODO: Preserve some residual damage when it makes sense.
3871 dam = 0;
3872 }
3873
3874 for( const ammo_effect_str_id &ae_id : proj.get_ammo_effects() ) {
3875 const ammo_effect &ae = *ae_id;
3876 if( ae.trail_field_type ) {
3877 if( x_in_y( ae.trail_chance, 100 ) ) {
3879 }
3880 }
3881 }
3882
3883 dam = std::max( 0.0f, dam );
3884
3885 // Check fields?
3886 const field_entry *fieldhit = get_field( p, fd_web );
3887 if( fieldhit != nullptr ) {
3888 if( inc ) {
3889 add_field( p, fd_fire, fieldhit->get_field_intensity() - 1 );
3890 } else if( dam > 5 + fieldhit->get_field_intensity() * 5 &&
3891 one_in( 5 - fieldhit->get_field_intensity() ) ) {
3892 dam -= rng( 1, 2 + fieldhit->get_field_intensity() * 2 );
3893 remove_field( p, fd_web );
3894 }
3895 }
3896
3897 // Rescale the damage
3898 if( dam <= 0 ) {
3899 proj.impact.damage_units.clear();
3900 return;
3901 } else if( dam < initial_damage ) {
3902 proj.impact.mult_damage( dam / static_cast<double>( initial_damage ) );
3903 }
3904
3905 //Projectiles with NO_ITEM_DAMAGE flag won't damage items at all
3906 if( !hit_items || !inbounds( p ) ) {
3907 return;
3908 }
3909
3910 // Make sure the message is sensible for the ammo effects. Lasers aren't projectiles.
3911 std::string damage_message;
3912 if( proj.has_effect( ammo_effect_LASER ) ) {
3913 damage_message = _( "laser beam" );
3914 } else if( proj.has_effect( ammo_effect_LIGHTNING ) ) {
3915 damage_message = _( "bolt of electricity" );
3916 } else if( proj.has_effect( ammo_effect_PLASMA ) ) {
3917 damage_message = _( "bolt of plasma" );
3918 } else {
3919 damage_message = _( "flying projectile" );
3920 }
3921
3922 smash_trap( p, dam, damage_message );
3923 smash_items( p, dam, damage_message, false );
3924}
void smash_trap(const tripoint &p, const int power, const std::string &cause_message)
Tries to smash the trap at the given tripoint.
Definition: map.cpp:3052
@ DT_STAB
Definition: damage.h:27
static const ammo_effect_str_id ammo_effect_LIGHTNING("LIGHTNING")
static const ammo_effect_str_id ammo_effect_LASER("LASER")
static const ammo_effect_str_id ammo_effect_INCENDIARY("INCENDIARY")
static const ammo_effect_str_id ammo_effect_PLASMA("PLASMA")
int check(unformattable)
Definition: fmtlib_core.h:1610
int trail_chance
Definition: ammo_effect.h:45
int trail_intensity_max
Definition: ammo_effect.h:44
int trail_intensity_min
Definition: ammo_effect.h:43
field_type_id trail_field_type
Definition: ammo_effect.h:40
std::vector< damage_unit > damage_units
Definition: damage.h:52
float type_damage(damage_type dt) const
Definition: damage.cpp:64
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
float damage_multiplier
Definition: damage.h:40
float res_pen
Definition: damage.h:38
const std::set< ammo_effect_str_id > & get_ammo_effects()
Definition: projectile.h:42
damage_instance impact
Definition: projectile.h:21
bool has_effect(const ammo_effect_str_id &id) const
Definition: projectile.h:55
bool flammable
Definition: mapdata.h:40
numeric_interval< int > reduction
Definition: mapdata.h:36
int destroy_threshold
Definition: mapdata.h:39
std::optional< numeric_interval< int > > reduction_laser
Definition: mapdata.h:38
units::probability block_unaimed_chance
Definition: mapdata.h:41

References _, add_field(), add_msg(), sounds::alarm, ammo_effect_INCENDIARY, ammo_effect_LASER, ammo_effect_LIGHTNING, ammo_effect_PLASMA, damage_unit::amount, bash(), bash_ter_success(), ranged_bash_info::block_unaimed_chance, detail::check(), damage_unit::damage_multiplier, damage_instance::damage_units, ranged_bash_info::destroy_threshold, DT_HEAT, DT_STAB, fd_fire, fd_web, ranged_bash_info::flammable, g, projectile::get_ammo_effects(), get_avatar(), get_field(), field_entry::get_field_intensity(), getabs(), projectile::has_effect(), has_flag(), projectile::impact, impassable(), inbounds(), is_transparent(), ms_to_sm_copy(), damage_instance::mult_damage(), one_in(), ranged_bash_info::reduction, ranged_bash_info::reduction_laser, remove_field(), damage_unit::res_pen, rng(), sees(), smash_items(), smash_trap(), sounds::sound(), ter(), tername(), terrain, TIMED_EVENT_WANTED, ammo_effect::trail_chance, ammo_effect::trail_field_type, ammo_effect::trail_intensity_max, ammo_effect::trail_intensity_min, calendar::turn, damage_instance::type_damage(), veh_at(), and x_in_y().

Referenced by ranged::execute_shaped_attack(), and projectile_attack().

◆ smash_items()

void map::smash_items ( const tripoint p,
int  power,
const std::string &  cause_message,
bool  do_destroy 
)

Tries to smash the items at the given tripoint.

Definition at line 3072 of file map.cpp.

3074{
3075 if( !has_items( p ) ) {
3076 return;
3077 }
3078
3079 // Keep track of how many items have been damaged, and what the first one is
3080 int items_damaged = 0;
3081 int items_destroyed = 0;
3082 std::string damaged_item_name;
3083
3084 // TODO: Bullets should be pretty much corpse-only
3085 constexpr const int min_destroy_threshold = 50;
3086
3087 std::vector<item> contents;
3088 map_stack items = i_at( p );
3089 for( auto it = items.begin(); it != items.end(); ) {
3090 if( it->has_flag( "EXPLOSION_SMASHED" ) ) {
3091 it++;
3092 continue;
3093 }
3094
3095 // detonate them if they can be exploded
3096 // We need to make a copy because the iterator validity is not predictable
3097 // see map_field.cpp process_fields_in_submap
3098 if( will_explode_on_impact( power ) && it->will_explode_in_fire() ) {
3099 item copy = *it;
3100 it = items.erase( it );
3101 if( copy.detonate( p, contents ) ) {
3102 // Need to restart, iterators may not be valid
3103 it = items.begin();
3104 }
3105 continue;
3106 }
3107
3108 // If the power is low or it's not an explosion, only pulp rezing corpses
3109 if( ( power < min_destroy_threshold || !do_destroy ) && !it->can_revive() ) {
3110 it++;
3111 continue;
3112 }
3113
3114 // Active explosives arbitrarily get double the destroy threshold
3115 bool is_active_explosive = it->active && it->type->get_use( "explosion" ) != nullptr;
3116 if( is_active_explosive && it->charges == 0 ) {
3117 it++;
3118 continue;
3119 }
3120
3121 const float material_factor = it->chip_resistance( true );
3122 // Intact non-rezing get a boost
3123 const float intact_mult = 2.0f -
3124 ( static_cast<float>( it->damage_level( it->max_damage() ) ) / it->max_damage() );
3125 const float destroy_threshold = min_destroy_threshold
3126 + material_factor * intact_mult;
3127 // For pulping, only consider material resistance. Non-rezing can only be destroyed.
3128 const float pulp_threshold = it->can_revive() ? material_factor : destroy_threshold;
3129 // Active explosives that will explode this turn are indestructible (they are exploding "now")
3130 if( power < pulp_threshold ) {
3131 it++;
3132 continue;
3133 }
3134
3135 bool item_was_destroyed = false;
3136 float destroy_chance = ( power - pulp_threshold ) / 4.0;
3137
3138 const bool by_charges = it->count_by_charges();
3139 if( by_charges ) {
3140 destroy_chance *= it->charges_per_volume( 250_ml );
3141 if( x_in_y( destroy_chance, destroy_threshold ) ) {
3142 item_was_destroyed = true;
3143 }
3144 } else {
3145 const field_type_id type_blood = it->is_corpse() ? it->get_mtype()->bloodType() : fd_null;
3146 float roll = rng_float( 0.0, destroy_chance );
3147 if( roll >= destroy_threshold ) {
3148 item_was_destroyed = true;
3149 } else if( roll >= pulp_threshold ) {
3150 // Only pulp
3151 it->set_damage( it->max_damage() );
3152 // TODO: Blood streak cone away from explosion
3153 add_splash( type_blood, p, 1, destroy_chance );
3154 // If it was the first item to be damaged, note it
3155 if( items_damaged == 0 ) {
3156 damaged_item_name = it->tname();
3157 }
3158 items_damaged++;
3159 }
3160 }
3161
3162 // Remove them if they were damaged too much
3163 if( item_was_destroyed ) {
3164 // But save the contents, except for irremovable gunmods
3165 for( item *elem : it->contents.all_items_top() ) {
3166 if( !elem->is_irremovable() ) {
3167 contents.push_back( item( *elem ) );
3168 }
3169 }
3170
3171 if( items_damaged == 0 ) {
3172 damaged_item_name = it->tname();
3173 }
3174 it = i_rem( p, it );
3175 items_damaged++;
3176 items_destroyed++;
3177 } else {
3178 it++;
3179 }
3180 }
3181
3182 // Let the player know that the item was damaged if they can see it.
3183 if( items_destroyed > 1 && g->u.sees( p ) ) {
3184 add_msg( m_bad, _( "The %s destroys several items!" ), cause_message );
3185 } else if( items_destroyed == 1 && items_damaged == 1 && g->u.sees( p ) ) {
3186 //~ %1$s: the cause of destruction, %2$s: destroyed item name
3187 add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name );
3188 } else if( items_damaged > 1 && g->u.sees( p ) ) {
3189 add_msg( m_bad, _( "The %s damages several items." ), cause_message );
3190 } else if( items_damaged == 1 && g->u.sees( p ) ) {
3191 //~ %1$s: the cause of damage, %2$s: damaged item name
3192 add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name );
3193 }
3194
3195 for( const item &it : contents ) {
3196 add_item_or_charges( p, it );
3197 }
3198}
void add_splash(const field_type_id &type, const tripoint &center, int radius, int intensity)
Definition: map.cpp:5638
static bool will_explode_on_impact(const int power)
Definition: map.cpp:3044

References _, add_item_or_charges(), add_msg(), add_splash(), item_contents::all_items_top(), item_stack::begin(), item::contents, item::detonate(), item_stack::end(), map_stack::erase(), fd_null, g, has_items(), i_at(), i_rem(), m_bad, rng_float(), will_explode_on_impact(), and x_in_y().

Referenced by explosion_handler::ExplosionProcess::blast_tile(), explosion_handler::legacy_blast(), move_vehicle(), and shoot().

◆ smash_trap()

void map::smash_trap ( const tripoint p,
const int  power,
const std::string &  cause_message 
)

Tries to smash the trap at the given tripoint.

Definition at line 3052 of file map.cpp.

3053{
3054 const trap &tr = get_map().tr_at( p );
3055 if( tr.is_null() ) {
3056 return;
3057 }
3058
3059 const bool is_explosive_trap = !tr.is_benign() && tr.vehicle_data.do_explosion;
3060
3061 if( !will_explode_on_impact( power ) || !is_explosive_trap ) {
3062 return;
3063 }
3064 // make a fake NPC to trigger the trap
3065 npc dummy;
3066 dummy.set_fake( true );
3067 dummy.name = cause_message;
3068 dummy.setpos( p );
3069 tr.trigger( p, &dummy );
3070}
virtual void set_fake(bool fake_value)
Sets a Creature's fake boolean.
Definition: creature.cpp:982
vehicle_handle_trap_data vehicle_data
Definition: trap.h:122
bool is_benign() const
If true, this is not really a trap and there won't be any safety queries before stepping onto it (e....
Definition: trap.h:159

References vehicle_handle_trap_data::do_explosion, get_map(), trap::is_benign(), trap::is_null(), Character::name, Creature::set_fake(), npc::setpos(), tr_at(), trap::trigger(), trap::vehicle_data, and will_explode_on_impact().

Referenced by explosion_handler::ExplosionProcess::blast_tile(), and shoot().

◆ spawn_an_item() [1/2]

item & map::spawn_an_item ( const tripoint p,
item  new_item,
int  charges,
int  damlevel 
)

Definition at line 4242 of file map.cpp.

4244{
4245 if( charges && new_item.charges > 0 ) {
4246 //let's fail silently if we specify charges for an item that doesn't support it
4247 new_item.charges = charges;
4248 }
4249 new_item = new_item.in_its_container();
4250 if( ( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) ||
4251 has_flag( "DESTROY_ITEM", p ) ) {
4252 return null_item_reference();
4253 }
4254
4255 new_item.set_damage( damlevel );
4256
4257 return add_item_or_charges( p, new_item );
4258}
item & set_damage(int qty)
Filter setting damage constrained by min_damage and max_damage.
Definition: item.cpp:714
item in_its_container() const
Returns this item into its default container.
Definition: item.cpp:841

References add_item_or_charges(), item::charges, has_flag(), item::in_its_container(), LIQUID, item::made_of(), null_item_reference(), and item::set_damage().

Referenced by salvage_actor::cut_up(), spawn_an_item(), and spawn_item().

◆ spawn_an_item() [2/2]

void map::spawn_an_item ( point  p,
item  new_item,
int  charges,
int  damlevel 
)
inline

Definition at line 1252 of file map.h.

1252 {
1253 spawn_an_item( tripoint( p, abs_sub.z ), new_item, charges, damlevel );
1254 }
item & spawn_an_item(const tripoint &p, item new_item, int charges, int damlevel)
Definition: map.cpp:4242

References abs_sub, spawn_an_item(), and tripoint::z.

◆ spawn_artifact()

void map::spawn_artifact ( const tripoint p)

Definition at line 4281 of file map.cpp.

4282{
4284}
itype_id new_artifact()
Definition: artifact.cpp:677

References add_item_or_charges(), new_artifact(), and calendar::start_of_cataclysm.

Referenced by draw_mine(), and draw_temple().

◆ spawn_item() [1/4]

void map::spawn_item ( const tripoint p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)

Definition at line 4291 of file map.cpp.

4294{
4295 if( type_id.is_null() ) {
4296 return;
4297 }
4298
4299 if( item_is_blacklisted( type_id ) ) {
4300 return;
4301 }
4302 // recurse to spawn (quantity - 1) items
4303 for( size_t i = 1; i < quantity; i++ ) {
4304 spawn_item( p, type_id, 1, charges, birthday, damlevel );
4305 }
4306 // spawn the item
4307 item new_item( type_id, birthday );
4308 if( one_in( 3 ) && new_item.has_flag( "VARSIZE" ) ) {
4309 new_item.set_flag( "FIT" );
4310 }
4311
4312 spawn_an_item( p, new_item, charges, damlevel );
4313}
bool is_null() const
Returns whether this represents the id of the null-object (in which case it's the null-id).
Definition: string_id.h:317
bool item_is_blacklisted(const itype_id &id)

References item::has_flag(), string_id< T >::is_null(), item_is_blacklisted(), one_in(), item::set_flag(), spawn_an_item(), and spawn_item().

Referenced by computer_session::action_extract_rad_source(), jmapgen_spawn_item::apply(), MapExtras::burned_ground_parser(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), activity_handlers::chop_planks_finish(), create_burnproducts(), iexamine::curtains(), vehicle::damage_direct(), monexamine::deactivate_pet(), MapExtras::dead_vegetation_parser(), game::disable_robot(), construct::done_window_curtains(), draw_lab(), draw_mine(), draw_office_tower(), explosion_handler::emp_blast(), iexamine::fertilize_plant(), dig_activity_actor::finish(), iexamine::flower_marloss(), activity_handlers::hacksaw_finish(), vehicle::handle_trap(), mapgen_cavern(), mapgen_tutorial(), MapExtras::mx_casings(), MapExtras::mx_drugdeal(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_roadworks(), om_cutdown_trees(), trap::on_disarmed(), activity_handlers::oxytorch_finish(), pick_plant(), mission_start::place_deposit_box(), MapExtras::place_fumarole(), mission_start::place_priest_diary(), place_vending(), activity_handlers::pry_nails_finish(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), iexamine::recycle_compactor(), iexamine::shrub_marloss(), sinkhole_safety_roll(), spawn_item(), Character::suffer_from_other_mutations(), iexamine::tree_hickory(), iexamine::tree_marloss(), try_remove_bear_trap(), try_remove_heavysnare(), try_remove_lightsnare(), unroll_digging(), and game::vertical_move().

◆ spawn_item() [2/4]

void map::spawn_item ( const tripoint p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1213 of file map.h.

1215 {
1216 spawn_item( p, itype_id( type_id ), quantity, charges, birthday, damlevel );
1217 }

References itype_id, and spawn_item().

◆ spawn_item() [3/4]

void map::spawn_item ( point  p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1205 of file map.h.

1207 {
1208 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1209 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [4/4]

void map::spawn_item ( point  p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1218 of file map.h.

1220 {
1221 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1222 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_items() [1/2]

std::vector< item * > map::spawn_items ( const tripoint p,
const std::vector< item > &  new_items 
)

Definition at line 4260 of file map.cpp.

4261{
4262 std::vector<item *> ret;
4263 if( !inbounds( p ) || has_flag( "DESTROY_ITEM", p ) ) {
4264 return ret;
4265 }
4266 const bool swimmable = has_flag( "SWIMMABLE", p );
4267 for( const item &new_item : new_items ) {
4268
4269 if( new_item.made_of( LIQUID ) && swimmable ) {
4270 continue;
4271 }
4272 item &it = add_item_or_charges( p, new_item );
4273 if( !it.is_null() ) {
4274 ret.push_back( &it );
4275 }
4276 }
4277
4278 return ret;
4279}
bool is_null() const
Definition: item.cpp:732

References add_item_or_charges(), has_flag(), inbounds(), item::is_null(), LIQUID, and cata::hash64_detail::ret.

Referenced by jmapgen_loot::apply(), bash_furn_success(), bash_items(), bash_ter_success(), activity_handlers::clear_rubble_finish(), complete_construction(), construct::done_deconstruct(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), talk_function::loot_building(), MapExtras::mx_casings(), MapExtras::mx_corpses(), process_fields_in_submap(), put_items_from_loc(), veh_utils::repair_part(), smash(), and spawn_items().

◆ spawn_items() [2/2]

void map::spawn_items ( point  p,
const std::vector< item > &  new_items 
)
inline

Definition at line 1328 of file map.h.

1328 {
1329 spawn_items( tripoint( p, abs_sub.z ), new_items );
1330 }

References abs_sub, spawn_items(), and tripoint::z.

◆ spawn_monsters()

void map::spawn_monsters ( bool  ignore_sight)

Spawn monsters from submap spawn points and from the overmap.

Parameters
ignore_sightIf true, monsters may spawn in the view of the player character (useful when the whole map has been loaded instead, e.g. when starting a new game, or after teleportation or after moving vertically). If false, monsters are not spawned in view of player character.

Definition at line 7817 of file map.cpp.

7818{
7819 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
7820 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
7821 tripoint gp;
7822 int &gx = gp.x;
7823 int &gy = gp.y;
7824 int &gz = gp.z;
7825 for( gz = zmin; gz <= zmax; gz++ ) {
7826 for( gx = 0; gx < my_MAPSIZE; gx++ ) {
7827 for( gy = 0; gy < my_MAPSIZE; gy++ ) {
7828 spawn_monsters_submap( gp, ignore_sight );
7829 }
7830 }
7831 }
7832}
void spawn_monsters_submap(const tripoint &gp, bool ignore_sight)
Definition: map.cpp:7762

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, spawn_monsters_submap(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn(), editmap::mapgen_preview(), game::place_player_overmap(), game::start_game(), game::update_map(), and game::vertical_shift().

◆ spawn_monsters_submap()

void map::spawn_monsters_submap ( const tripoint gp,
bool  ignore_sight 
)
private

Definition at line 7762 of file map.cpp.

7763{
7764 // Load unloaded monsters
7765 // TODO: fix point types
7767
7768 // Only spawn new monsters after existing monsters are loaded.
7769 // TODO: fix point types
7770 auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) );
7771 for( auto &mgp : groups ) {
7772 spawn_monsters_submap_group( gp, *mgp, ignore_sight );
7773 }
7774
7775 submap *const current_submap = get_submap_at_grid( gp );
7776 const tripoint gp_ms = sm_to_ms_copy( gp );
7777
7778 for( auto &i : current_submap->spawns ) {
7779 const tripoint center = gp_ms + i.pos;
7781
7782 for( int j = 0; j < i.count; j++ ) {
7783 monster tmp( i.type );
7784 tmp.mission_id = i.mission_id;
7785 if( i.name != "NONE" ) {
7786 tmp.unique_name = i.name;
7787 }
7788 if( i.friendly ) {
7789 tmp.friendly = -1;
7790 }
7791
7792 const auto valid_location = [&]( const tripoint & p ) {
7793 // Checking for creatures via g is only meaningful if this is the main game map.
7794 // If it's some local map instance, the coordinates will most likely not even match.
7795 return ( !g || &get_map() != this || !g->critter_at( p ) ) && tmp.can_move_to( p );
7796 };
7797
7798 const auto place_it = [&]( const tripoint & p ) {
7799 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7800 if( placed ) {
7801 placed->on_load();
7802 }
7803 };
7804
7805 // First check out defined spawn location for a valid placement, and if that doesn't work
7806 // then fall back to picking a random point that is a valid location.
7807 if( valid_location( center ) ) {
7808 place_it( center );
7809 } else if( const std::optional<tripoint> pos = random_point( points, valid_location ) ) {
7810 place_it( *pos );
7811 }
7812 }
7813 }
7814 current_submap->spawns.clear();
7815}
void spawn_monsters_submap_group(const tripoint &gp, mongroup &group, bool ignore_sight)
Definition: map.cpp:7628
void on_load()
Retroactively update monster.
Definition: monster.cpp:3007
std::vector< mongroup * > groups_at(const tripoint_abs_sm &p)
Monster groups at p - absolute submap coordinates.
void spawn_monster(const tripoint_abs_sm &p)
Spawn monsters from the overmap onto the main map (game::m).

References abs_sub, monster::can_move_to(), center, monster::friendly, g, get_map(), get_submap_at_grid(), overmapbuffer::groups_at(), monster::mission_id, monster::on_load(), overmap_buffer, points_in_radius(), random_point(), sm_to_ms_copy(), overmapbuffer::spawn_monster(), spawn_monsters_submap_group(), submap::spawns, monster::unique_name, and tripoint::xy().

Referenced by spawn_monsters().

◆ spawn_monsters_submap_group()

void map::spawn_monsters_submap_group ( const tripoint gp,
mongroup group,
bool  ignore_sight 
)
private

Definition at line 7628 of file map.cpp.

7629{
7630 const int s_range = std::min( HALF_MAPSIZE_X,
7631 g->u.sight_range( g->light_level( g->u.posz() ) ) );
7632 int pop = group.population;
7633 std::vector<tripoint> locations;
7634 if( !ignore_sight ) {
7635 // If the submap is one of the outermost submaps, assume that monsters are
7636 // invisible there.
7637 if( gp.x == 0 || gp.y == 0 || gp.x + 1 == MAPSIZE || gp.y + 1 == MAPSIZE ) {
7638 ignore_sight = true;
7639 }
7640 }
7641
7642 if( gp.z != g->u.posz() ) {
7643 // Note: this is only OK because 3D vision isn't a thing yet
7644 ignore_sight = true;
7645 }
7646
7647 static const auto allow_on_terrain = [&]( const tripoint & p ) {
7648 // TODO: flying creatures should be allowed to spawn without a floor,
7649 // but the new creature is created *after* determining the terrain, so
7650 // we can't check for it here.
7651 return passable( p ) && has_floor( p );
7652 };
7653
7654 // If the submap is uniform, we can skip many checks
7655 const submap *current_submap = get_submap_at_grid( gp );
7656 bool ignore_terrain_checks = false;
7657 bool ignore_inside_checks = gp.z < 0;
7658 if( current_submap->is_uniform ) {
7659 const tripoint upper_left{ SEEX * gp.x, SEEY * gp.y, gp.z };
7660 if( !allow_on_terrain( upper_left ) ||
7661 ( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, upper_left ) ) ) {
7662 const tripoint glp = getabs( gp );
7663 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7664 << " at uniform submap " << gp << " global " << glp;
7665 return;
7666 }
7667
7668 ignore_terrain_checks = true;
7669 ignore_inside_checks = true;
7670 }
7671
7672 for( int x = 0; x < SEEX; ++x ) {
7673 for( int y = 0; y < SEEY; ++y ) {
7674 int fx = x + SEEX * gp.x;
7675 int fy = y + SEEY * gp.y;
7676 tripoint fp{ fx, fy, gp.z };
7677 if( g->critter_at( fp ) != nullptr ) {
7678 continue; // there is already some creature
7679 }
7680
7681 if( !ignore_terrain_checks && !allow_on_terrain( fp ) ) {
7682 continue; // solid area, impassable
7683 }
7684
7685 if( !ignore_sight && sees( g->u.pos(), fp, s_range ) ) {
7686 continue; // monster must spawn outside the viewing range of the player
7687 }
7688
7689 if( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, fp ) ) {
7690 continue; // monster must spawn outside.
7691 }
7692
7693 locations.push_back( fp );
7694 }
7695 }
7696
7697 if( locations.empty() ) {
7698 // TODO: what now? there is no possible place to spawn monsters, most
7699 // likely because the player can see all the places.
7700 const tripoint glp = getabs( gp );
7701 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7702 << " at " << gp << " global " << glp;
7703 // Just kill the group. It's not like we're removing existing monsters
7704 // Unless it's a horde - then don't kill it and let it spawn behind a tree or smoke cloud
7705 if( !group.horde ) {
7706 group.clear();
7707 }
7708
7709 return;
7710 }
7711
7712 if( pop ) {
7713 // Populate the group from its population variable.
7714 for( int m = 0; m < pop; m++ ) {
7716 if( !spawn_details.name ) {
7717 continue;
7718 }
7719 monster tmp( spawn_details.name );
7720
7721 // If a monster came from a horde population, configure them to always be willing to rejoin a horde.
7722 if( group.horde ) {
7723 tmp.set_horde_attraction( MHA_ALWAYS );
7724 }
7725 for( int i = 0; i < spawn_details.pack_size; i++ ) {
7726 group.monsters.push_back( tmp );
7727 }
7728 }
7729 }
7730
7731 // Find horde's target submap
7732 // TODO: fix point types
7733 tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() );
7734 sm_to_ms( horde_target );
7735 for( auto &tmp : group.monsters ) {
7736 for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) {
7738 if( !tmp.can_move_to( p ) ) {
7739 continue; // target can not contain the monster
7740 }
7741 if( group.horde ) {
7742 // Give monster a random point near horde's expected destination
7743 const tripoint rand_dest = horde_target +
7744 point( rng( 0, SEEX ), rng( 0, SEEY ) );
7745 const int turns = rl_dist( p, rand_dest ) + group.interest;
7746 tmp.wander_to( rand_dest, turns );
7747 add_msg( m_debug, "%s targeting %d,%d,%d", tmp.disp_name(),
7748 tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z );
7749 }
7750
7751 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7752 if( placed ) {
7753 placed->on_load();
7754 }
7755 break;
7756 }
7757 }
7758 // indicates the group is empty, and can be removed later
7759 group.clear();
7760}
void sm_to_ms(int &x, int &y)
static constexpr int HALF_MAPSIZE_X
@ MHA_ALWAYS
Definition: monster.h:76
generic_factory< overmap_location > locations("overmap location")

References abs_sub, add_msg(), dbg, g, get_submap_at_grid(), getabs(), MonsterGroupManager::GetResultFromGroup(), HALF_MAPSIZE_X, has_flag_ter_or_furn(), has_floor(), submap::is_uniform, anonymous_namespace{overmap_location.cpp}::locations, m_debug, MAPSIZE, MHA_ALWAYS, MonsterGroupResult::name, monster::on_load(), MonsterGroupResult::pack_size, passable(), random_entry_removed(), rl_dist(), rng(), sees(), SEEX, SEEY, monster::set_horde_attraction(), sm_to_ms(), TFLAG_INDOORS, Warn, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by spawn_monsters_submap().

◆ spawn_natural_artifact()

void map::spawn_natural_artifact ( const tripoint p,
artifact_natural_property  prop 
)

Definition at line 4286 of file map.cpp.

4287{
4289}
itype_id new_natural_artifact(artifact_natural_property prop)
Definition: artifact.cpp:931

References add_item_or_charges(), new_natural_artifact(), and calendar::start_of_cataclysm.

Referenced by debug_menu::debug(), and MapExtras::mx_portal_in().

◆ spread_gas()

void map::spread_gas ( field_entry cur,
const tripoint p,
int  percent_spread,
const time_duration outdoor_age_speedup,
scent_block sblk 
)
private

Definition at line 251 of file map_field.cpp.

253{
254 map &here = get_map();
255 // TODO: fix point types
256 const oter_id &cur_om_ter =
258 const bool sheltered = g->is_sheltered( p );
260 const int winddirection = weather.winddirection;
261 const int windpower = get_local_windpower( weather.windspeed, cur_om_ter, p, winddirection,
262 sheltered );
263
264 const int current_intensity = cur.get_field_intensity();
265 const field_type_id ft_id = cur.get_field_type();
266
267 const int scent_neutralize = ft_id->get_intensity_level( current_intensity -
269
270 if( scent_neutralize > 0 ) {
271 // modify scents by neutralization value (minus)
272 for( const tripoint &tmp : points_in_radius( p, 1 ) ) {
273 sblk.apply_gas( tmp, scent_neutralize );
274 }
275 }
276
277 // Dissipate faster outdoors.
278 if( is_outside( p ) ) {
279 const time_duration current_age = cur.get_field_age();
280 cur.set_field_age( current_age + outdoor_age_speedup );
281 }
282
283 // Bail out if we don't meet the spread chance or required intensity.
284 if( current_intensity <= 1 || rng( 1, 100 - windpower ) > percent_spread ) {
285 return;
286 }
287
288 // First check if we can fall
289 // TODO: Make fall and rise chances parameters to enable heavy/light gas
290 if( zlevels && p.z > -OVERMAP_DEPTH ) {
291 const tripoint down{ p.xy(), p.z - 1 };
292 if( gas_can_spread_to( cur, p, down ) && valid_move( p, down, true, true ) ) {
293 maptile down_tile = maptile_at_internal( down );
294 gas_spread_to( cur, down_tile, down );
295 return;
296 }
297 }
298
299 auto neighs = get_neighbors( p );
300 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
301 std::vector<size_t> spread;
302 std::vector<size_t> neighbour_vec;
303 // Then, spread to a nearby point.
304 // If not possible (or randomly), try to spread up
305 // Wind direction will block the field spreading into the wind.
306 // Start at end_it + 1, then wrap around until all elements have been processed.
307 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
308 count != neighs.size();
309 i = ( i + 1 ) % neighs.size(), count++ ) {
310 const auto &neigh = neighs[i];
311 if( gas_can_spread_to( cur, p, neigh.first ) ) {
312 spread.push_back( i );
313 }
314 }
315 auto maptiles = get_wind_blockers( winddirection, p );
316 // Three map tiles that are facing the wind direction.
317 const maptile remove_tile = std::get<0>( maptiles );
318 const maptile remove_tile2 = std::get<1>( maptiles );
319 const maptile remove_tile3 = std::get<2>( maptiles );
320 if( !spread.empty() && ( !zlevels || one_in( spread.size() ) ) ) {
321 // Construct the destination from offset and p
322 if( g->is_sheltered( p ) || windpower < 5 ) {
323 std::pair<tripoint, maptile> &n = neighs[ random_entry( spread ) ];
324 gas_spread_to( cur, n.second, n.first );
325 } else {
326 end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
327 // Start at end_it + 1, then wrap around until all elements have been processed.
328 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
329 count != neighs.size();
330 i = ( i + 1 ) % neighs.size(), count++ ) {
331 const auto &neigh = neighs[i].second;
332 if( ( neigh.pos_.x != remove_tile.pos_.x && neigh.pos_.y != remove_tile.pos_.y ) ||
333 ( neigh.pos_.x != remove_tile2.pos_.x && neigh.pos_.y != remove_tile2.pos_.y ) ||
334 ( neigh.pos_.x != remove_tile3.pos_.x && neigh.pos_.y != remove_tile3.pos_.y ) ) {
335 neighbour_vec.push_back( i );
336 } else if( x_in_y( 1, std::max( 2, windpower ) ) ) {
337 neighbour_vec.push_back( i );
338 }
339 }
340 if( !neighbour_vec.empty() ) {
341 std::pair<tripoint, maptile> &n = neighs[neighbour_vec[rng( 0, neighbour_vec.size() - 1 )]];
342 gas_spread_to( cur, n.second, n.first );
343 }
344 }
345 } else if( zlevels && p.z < OVERMAP_HEIGHT ) {
346 const tripoint up{ p.xy(), p.z + 1 };
347 if( gas_can_spread_to( cur, p, up ) && valid_move( p, up, true, true ) ) {
348 maptile up_tile = maptile_at_internal( up );
349 gas_spread_to( cur, up_tile, up );
350 }
351 }
352}
std::tuple< maptile, maptile, maptile > get_wind_blockers(const int &winddirection, const tripoint &pos)
Definition: map_field.cpp:1893
bool gas_can_spread_to(field_entry &cur, const tripoint &src, const tripoint &dst)
Definition: map_field.cpp:211
void gas_spread_to(field_entry &cur, maptile &dst, const tripoint &p)
Definition: map_field.cpp:225
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
const field_intensity_level & get_intensity_level(int level=0) const
Definition: field_type.cpp:130
point pos_
Definition: submap.h:243
void apply_gas(const tripoint &p, const int nintensity=0)
Definition: scent_block.cpp:45

References scent_block::apply_gas(), detail::count(), g, gas_can_spread_to(), gas_spread_to(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_type::get_intensity_level(), get_local_windpower(), get_map(), get_neighbors(), get_weather(), get_wind_blockers(), getabs(), is_outside(), maptile_at_internal(), ms_to_omt_copy(), one_in(), overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), maptile::pos_, random_entry(), rng(), field_intensity_level::scent_neutralization, field_entry::set_field_age(), overmapbuffer::ter(), valid_move(), point::x, x_in_y(), tripoint::xy(), point::y, tripoint::z, and zlevels.

Referenced by process_fields_in_submap().

◆ stored_volume()

units::volume map::stored_volume ( const tripoint p)

Definition at line 4321 of file map.cpp.

4322{
4323 return i_at( p ).stored_volume();
4324}
units::volume stored_volume() const
Total volume of the items here.
Definition: item_stack.cpp:98

References i_at(), and item_stack::stored_volume().

◆ support_dirty()

void map::support_dirty ( const tripoint p)
private

Definition at line 2348 of file map.cpp.

2349{
2350 if( zlevels ) {
2351 support_cache_dirty.insert( p );
2352 }
2353}

References support_cache_dirty, and zlevels.

Referenced by add_field(), add_item_or_charges(), drop_furniture(), furn_set(), ter_set(), and update_suspension_cache().

◆ supports_above()

bool map::supports_above ( const tripoint p) const

Does this tile support vehicles and furniture above it.

Definition at line 2101 of file map.cpp.

2102{
2103 const maptile tile = maptile_at( p );
2104 const ter_t &ter = tile.get_ter_t();
2105 if( ter.movecost == 0 ) {
2106 return true;
2107 }
2108
2109 const furn_id frn_id = tile.get_furn();
2110 if( frn_id != f_null ) {
2111 const furn_t &frn = frn_id.obj();
2112 if( frn.movecost < 0 ) {
2113 return true;
2114 }
2115 }
2116
2117 return veh_at( p ).has_value();
2118}
furn_id get_furn() const
Definition: submap.h:256

References f_null, maptile::get_furn(), maptile::get_ter_t(), maptile_at(), map_data_common_t::movecost, int_id< T >::obj(), ter(), and veh_at().

Referenced by vehicle::check_falling_or_floating(), and drop_furniture().

◆ ter() [1/2]

ter_id map::ter ( const tripoint p) const

Definition at line 1562 of file map.cpp.

1563{
1564 if( !inbounds( p ) ) {
1565 return t_null;
1566 }
1567
1568 point l;
1569 submap *const current_submap = get_submap_at( p, l );
1570
1571 return current_submap->get_ter( l );
1572}

References get_submap_at(), submap::get_ter(), inbounds(), and t_null.

Referenced by computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_elevator_on(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), computer_session::action_srcf_elevator(), computer_session::action_srcf_seal(), actualize(), ter_furn_transform::add_all_messages(), add_boardable(), apply< ter_t >(), cata_event_dispatch::avatar_moves(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), can_construct(), can_do_activity_there(), can_examine_at(), iexamine::cardreader(), iexamine::cardreader_foodplace(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), vehicle::check_heli_ascend(), activity_handlers::chop_logs_finish(), chop_tree_activity(), activity_handlers::chop_tree_finish(), close_door(), complete_construction(), coverage(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), determine_wall_corner(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), editmap_hilight::draw(), draw_connections(), draw_lab(), editmap::draw_main_ui_overlay(), draw_mine(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_data(), computer_session::failure_pump_explode(), computer_session::failure_pump_leak(), feature< ter_id >(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), activity_handlers::fill_pit_finish(), find_base_construction(), game::find_or_make_stairs(), find_potential_computer_point(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), Character::floor_bedding_warmth(), fromPumpFuel(), iexamine::fswitch(), gas_can_spread_to(), generic_multi_activity_locations(), get_changed_ids_from_update(), get_hack_type(), get_harvest(), get_harvest_names(), get_known_connections(), get_roof(), get_ter_transforms_into(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), activity_handlers::hacksaw_finish(), has_flag_ter(), has_neighbor(), has_pre_terrain(), hit_with_acid(), advanced_inv_area::init(), is_bashable(), is_bashable_ter(), anonymous_namespace{gates.cpp}::gate_data::is_suitable_wall(), is_suspension_valid(), iexamine::ledge(), talk_function::loot_building(), mapgen_ants_generic(), mapgen_lake_shore(), fungal_effects::marlossify(), map_stack::max_volume(), map_funcs::migo_nerve_cage_removal(), avatar_action::move(), move_cost(), move_vehicle(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_portal_in(), MapExtras::mx_shrubbery(), iexamine::nanofab(), obstacle_coverage(), om_cutdown_trees(), om_harvest_ter(), open(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), activity_handlers::pickaxe_finish(), iexamine::pit(), iexamine::pit_covered(), mission_start::place_deposit_box(), place_items(), game::place_player(), game::print_fields_info(), game::print_graffiti_info(), game::print_terrain_info(), process_fields_in_submap(), produce_sap(), activity_handlers::pry_nails_finish(), rad_scorch(), resolve_regional_terrain_and_furniture(), restock_fruits(), mission_start::reveal_lab_train_depot(), shoot(), supports_above(), temperature_flag_at_point(), rot::temperature_flag_for_location(), ter(), tername(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), trap_set(), avatar_funcs::try_to_sleep(), turnOnSelectedPump(), Character::update_bodytemp(), update_suspension_cache(), editmap::update_view_with_help(), pick_lock_actor::use(), vehicle_wheel_traction(), game::vertical_move(), game::walk_move(), and water_from().

◆ ter() [2/2]

ter_id map::ter ( point  p) const
inline

Definition at line 816 of file map.h.

816 {
817 return ter( tripoint( p, abs_sub.z ) );
818 }

References abs_sub, ter(), and tripoint::z.

◆ ter_set() [1/2]

bool map::ter_set ( const tripoint p,
const ter_id new_terrain 
)

Definition at line 1703 of file map.cpp.

1704{
1705 if( !inbounds( p ) ) {
1706 return false;
1707 }
1708
1709 point l;
1710 submap *const current_submap = get_submap_at( p, l );
1711 const ter_id old_id = current_submap->get_ter( l );
1712 if( old_id == new_terrain ) {
1713 // Nothing changed
1714 return false;
1715 }
1716
1717 current_submap->set_ter( l, new_terrain );
1718
1719 // Set the dirty flags
1720 const ter_t &old_t = old_id.obj();
1721 const ter_t &new_t = new_terrain.obj();
1722
1723 // HACK: Hack around ledges in traplocs or else it gets NASTY in z-level mode
1724 if( old_t.trap != tr_null && old_t.trap != tr_ledge ) {
1725 auto &traps = traplocs[old_t.trap.to_i()];
1726 const auto iter = std::find( traps.begin(), traps.end(), p );
1727 if( iter != traps.end() ) {
1728 traps.erase( iter );
1729 }
1730 }
1731 if( new_t.trap != tr_null && new_t.trap != tr_ledge ) {
1732 traplocs[new_t.trap.to_i()].push_back( p );
1733 }
1734
1735 if( old_t.transparent != new_t.transparent ) {
1738 }
1739
1740 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1742 }
1743
1744 if( new_t.has_flag( TFLAG_NO_FLOOR ) != old_t.has_flag( TFLAG_NO_FLOOR ) ) {
1746 // It's a set, not a flag
1747 support_cache_dirty.insert( p );
1749 }
1750
1751 if( new_t.has_flag( TFLAG_SUSPENDED ) != old_t.has_flag( TFLAG_SUSPENDED ) ) {
1753 if( new_t.has_flag( TFLAG_SUSPENDED ) ) {
1754 level_cache &ch = get_cache( p.z );
1755 ch.suspension_cache.emplace_back( getabs( p ).xy() );
1756 }
1757 }
1758
1760
1762
1763 // TODO: Limit to changes that affect move cost, traps and stairs
1765
1766 tripoint above( p.xy(), p.z + 1 );
1767 // Make sure that if we supported something and no longer do so, it falls down
1768 support_dirty( above );
1769
1770 return true;
1771}
std::list< point > suspension_cache
Definition: map.h:312
trap_id trap
Definition: mapdata.h:473

References detail::find(), get_cache(), get_submap_at(), submap::get_ter(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), int_id< T >::obj(), set_floor_cache_dirty(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), submap::set_ter(), set_transparency_cache_dirty(), support_cache_dirty, support_dirty(), level_cache::suspension_cache, TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUSPENDED, int_id< T >::to_i(), tr_ledge, tr_null, map_data_common_t::transparent, ter_t::trap, traplocs, tripoint::xy(), and tripoint::z.

Referenced by computer_session::action_elevator_on(), computer_session::action_srcf_elevator(), add_computer(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_setmap::apply(), apply< ter_t >(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), iexamine::cardreader(), iexamine::cardreader_foodplace(), iexamine::cardreader_robofac(), activity_handlers::chop_logs_finish(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), construct::done_ramp_high(), construct::done_ramp_low(), construct::done_wood_stairs(), draw_anthill(), draw_circle_ter(), draw_connections(), draw_lab(), draw_line_ter(), draw_mine(), draw_rough_circle_ter(), draw_slimepit(), draw_square_ter(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), computer_session::failure_pump_leak(), computer_session::failure_shutdown(), farm_action(), talk_function::field_harvest(), activity_handlers::fill_pit_finish(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), fromPumpFuel(), iexamine::fswitch(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), hit_with_acid(), talk_function::loot_building(), make_rubble(), mapgen_ants_curved(), mapgen_ants_four_way(), mapgen_ants_generic(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_hellmouth(), mapgen_highway(), mapgen_hive(), mapgen_lake_shore(), mapgen_null(), mapgen_parking_lot(), mapgen_rift(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rock_partial(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_test(), mapgen_tutorial(), fungal_effects::marlossify(), map_funcs::migo_nerve_cage_removal(), move_vehicle(), MapExtras::mx_bandits_block(), MapExtras::mx_clay_deposit(), MapExtras::mx_clearcut(), MapExtras::mx_grave(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_wasp(), MapExtras::mx_pond(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_shrubbery(), MapExtras::mx_spider(), om_cutdown_trees(), om_harvest_ter(), om_set_hide_site(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), pick_plant(), iexamine::pit(), iexamine::pit_covered(), MapExtras::place_fumarole(), place_gas_pump(), mission_start::place_npc_software(), process_fields_in_submap(), activity_handlers::pry_nails_finish(), rad_scorch(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), restock_fruits(), science_room(), set(), iexamine::shrub_marloss(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_set(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), iexamine::tree_hickory(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), turnOnSelectedPump(), and game::vertical_move().

◆ ter_set() [2/2]

bool map::ter_set ( point  p,
const ter_id new_terrain 
)
inline

Definition at line 841 of file map.h.

841 {
842 return ter_set( tripoint( p, abs_sub.z ), new_terrain );
843 }

References abs_sub, ter_set(), and tripoint::z.

◆ tername() [1/2]

◆ tername() [2/2]

std::string map::tername ( point  p) const
inline

Definition at line 846 of file map.h.

846 {
847 return tername( tripoint( p, abs_sub.z ) );
848 }

References abs_sub, tername(), and tripoint::z.

◆ tinder_at()

bool map::tinder_at ( const tripoint p)

Checks if there are any tinder flagged items on the tile.

Parameters
ptile to check

Definition at line 2676 of file map.cpp.

2677{
2678 for( const auto &i : i_at( p ) ) {
2679 if( i.has_flag( "TINDER" ) ) {
2680 return true;
2681 }
2682 }
2683 return false;
2684}

References i_at().

Referenced by activity_handlers::start_fire_do_turn().

◆ tr_at()

const trap & map::tr_at ( const tripoint p) const

Definition at line 5235 of file map.cpp.

5236{
5237 if( !inbounds( p ) ) {
5238 return tr_null.obj();
5239 }
5240
5241 point l;
5242 submap *const current_submap = get_submap_at( p, l );
5243
5244 if( current_submap->get_ter( l ).obj().trap != tr_null ) {
5245 return current_submap->get_ter( l ).obj().trap.obj();
5246 }
5247
5248 return current_submap->get_trap( l ).obj();
5249}

References get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), tr_null, and ter_t::trap.

Referenced by can_see_trap_at(), construct::check_empty(), construct::check_no_trap(), complete_construction(), construction_activity(), creature_on_trap(), disarm_trap(), draw_lab(), editmap::draw_main_ui_overlay(), drop_or_embed_projectile(), game::examine(), feature< trap_id >(), fill_funnels(), game::fling_creature(), Character::floor_bedding_warmth(), get_convection_temperature(), game::get_dangerous_tile(), game::grabbed_furn_move(), vehicle::handle_trap(), advanced_inv_area::init(), place_trap_actor::is_allowed(), trapfunc::map_regen(), MapExtras::mx_minefield(), MapExtras::mx_portal(), character_funcs::pick_safe_adjacent_tile(), place_and_add_as_known(), place_construction(), tutorial_game::post_action(), game::print_trap_info(), game::process_artifact(), relic_funcs::process_recharge_entry(), game::prompt_dangerous_tile(), iexamine::rubble(), character_funcs::search_surroundings(), iexamine::shrub_wildveggies(), sinkhole_safety_roll(), smash_trap(), iexamine::trap(), avatar_funcs::try_to_sleep(), editmap::update_view_with_help(), and valid_move().

◆ translate()

void map::translate ( const ter_id from,
const ter_id to 
)

Definition at line 4030 of file map.cpp.

4031{
4032 if( from == to ) {
4033 debugmsg( "map::translate %s => %s",
4034 from.obj().name(),
4035 from.obj().name() );
4036 return;
4037 }
4038 for( const tripoint &p : points_on_zlevel() ) {
4039 if( ter( p ) == from ) {
4040 ter_set( p, to );
4041 }
4042 }
4043}

References debugmsg, map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), and ter_set().

Referenced by jmapgen_translate::apply(), mapgen_lake_shore(), start_location::prepare_map(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and mission_start::ranch_scavenger_3().

◆ translate_radius()

void map::translate_radius ( const ter_id from,
const ter_id to,
float  radi,
const tripoint p,
bool  same_submap = false,
bool  toggle_between = false 
)

Definition at line 4046 of file map.cpp.

4048{
4049 if( from == to ) {
4050 debugmsg( "map::translate %s => %s", from.obj().name(), to.obj().name() );
4051 return;
4052 }
4053
4054 const tripoint abs_omt_p = ms_to_omt_copy( getabs( p ) );
4055 for( const tripoint &t : points_on_zlevel() ) {
4056 const tripoint abs_omt_t = ms_to_omt_copy( getabs( t ) );
4057 const float radiX = trig_dist( p, t );
4058 if( ter( t ) == from ) {
4059 // within distance, and either no submap limitation or same overmap coords.
4060 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
4061 ter_set( t, to );
4062 }
4063 } else if( toggle_between && ter( t ) == to ) {
4064 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
4065 ter_set( t, from );
4066 }
4067 }
4068 }
4069}

References debugmsg, getabs(), ms_to_omt_copy(), map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), ter_set(), and trig_dist().

Referenced by computer_session::action_extract_rad_source(), computer_session::action_irradiator(), computer_session::action_lock(), computer_session::action_open(), computer_session::action_release(), computer_session::action_release_bionics(), computer_session::action_shutters(), and computer_session::action_unlock().

◆ trap_locations()

const std::vector< tripoint > & map::trap_locations ( const trap_id type) const

Definition at line 7863 of file map.cpp.

7864{
7865 return traplocs[type.to_i()];
7866}

References traplocs, and type.

◆ trap_set()

void map::trap_set ( const tripoint p,
const trap_id type 
)

Definition at line 5287 of file map.cpp.

5288{
5289 if( !inbounds( p ) ) {
5290 return;
5291 }
5292
5293 point l;
5294 submap *const current_submap = get_submap_at( p, l );
5295 const ter_t &ter = current_submap->get_ter( l ).obj();
5296 if( ter.trap != tr_null ) {
5297 debugmsg( "set trap %s on top of terrain %s which already has a builit-in trap",
5298 type.obj().name(), ter.name() );
5299 return;
5300 }
5301
5302 // If there was already a trap here, remove it.
5303 if( current_submap->get_trap( l ) != tr_null ) {
5304 remove_trap( p );
5305 }
5306
5307 current_submap->set_trap( l, type );
5308 if( type != tr_null ) {
5309 traplocs[type.to_i()].push_back( p );
5310 }
5311}
void remove_trap(const tripoint &p)
Definition: map.cpp:5371

References debugmsg, get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), remove_trap(), submap::set_trap(), ter(), tr_null, traplocs, and type.

Referenced by jmapgen_trap::apply(), apply< trap >(), construction_activity(), construct::done_mark_firewood(), construct::done_mark_practice_target(), draw_lab(), vehicle::handle_trap(), mtrap_set(), MapExtras::mx_portal(), place_and_add_as_known(), place_construction(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ unboard_vehicle() [1/2]

void map::unboard_vehicle ( const tripoint p,
bool  dead_passenger = false 
)

Definition at line 1165 of file map.cpp.

1166{
1167 const std::optional<vpart_reference> vp = veh_at( p ).part_with_feature( VPFLAG_BOARDABLE, false );
1168 player *passenger = nullptr;
1169 if( !vp ) {
1170 debugmsg( "map::unboard_vehicle: vehicle not found" );
1171 // Try and force unboard the player anyway.
1172 passenger = g->critter_at<player>( p );
1173 if( passenger ) {
1174 passenger->in_vehicle = false;
1175 passenger->controlling_vehicle = false;
1176 }
1177 return;
1178 }
1179 passenger = vp->get_passenger();
1180 unboard_vehicle( *vp, passenger, dead_passenger );
1181}
bool controlling_vehicle
Definition: character.h:254

References Character::controlling_vehicle, debugmsg, g, Character::in_vehicle, optional_vpart_position::part_with_feature(), unboard_vehicle(), veh_at(), and VPFLAG_BOARDABLE.

◆ unboard_vehicle() [2/2]

void map::unboard_vehicle ( const vpart_reference vp,
Character passenger,
bool  dead_passenger = false 
)

Definition at line 1145 of file map.cpp.

1146{
1147 // Mark the part as un-occupied regardless of whether there's a live passenger here.
1149 vp.vehicle().invalidate_mass();
1150
1151 if( !passenger ) {
1152 if( !dead_passenger ) {
1153 debugmsg( "map::unboard_vehicle: passenger not found" );
1154 }
1155 return;
1156 }
1157 passenger->in_vehicle = false;
1158 // Only make vehicle go out of control if the driver is the one unboarding.
1159 if( passenger->controlling_vehicle ) {
1160 vp.vehicle().skidding = true;
1161 }
1162 passenger->controlling_vehicle = false;
1163}
void invalidate_mass()
Mark mass caches and pivot cache as dirty.
Definition: vehicle.cpp:6972
vehicle_part & part() const
Yields the vehicle_part object referenced by this.
Definition: vehicle.cpp:6775
::vehicle & vehicle() const

References Character::controlling_vehicle, debugmsg, Character::in_vehicle, vehicle::invalidate_mass(), vpart_reference::part(), vehicle_part::passenger_flag, vehicle_part::remove_flag(), vehicle::skidding, and vpart_reference::vehicle().

Referenced by board_vehicle(), iexamine::chainfence(), detach_vehicle(), game::fling_creature(), talk_function::individual_mission(), game::is_game_over(), npc::move_to(), game::moving_vehicle_dismount(), game::phasing_move(), game::place_player(), game::place_player_overmap(), mattack::ranged_pull(), shake_vehicle(), game::swap_critters(), avatar_action::swim(), unboard_vehicle(), and game::vertical_move().

◆ update_lum()

void map::update_lum ( item_location loc,
bool  add 
)

Update luminosity before and after item's transformation.

Definition at line 4544 of file map.cpp.

4545{
4546 item *target = loc.get_item();
4547
4548 // if the item is not emissive, do nothing
4549 if( !target->is_emissive() ) {
4550 return;
4551 }
4552
4553 point l;
4554 submap *const current_submap = get_submap_at( loc.position(), l );
4555
4556 if( add ) {
4557 current_submap->update_lum_add( l, *target );
4558 } else {
4559 current_submap->update_lum_rem( l, *target );
4560 }
4561}
bool is_emissive() const
Whether the item emits any light at all.
Definition: item.cpp:6943

References om_direction::add(), item_location::get_item(), get_submap_at(), item::is_emissive(), item_location::position(), submap::update_lum_add(), and submap::update_lum_rem().

Referenced by update_lum().

◆ update_pathfinding_cache()

void map::update_pathfinding_cache ( int  zlev) const

Definition at line 8974 of file map.cpp.

8975{
8976 auto &cache = get_pathfinding_cache( zlev );
8977 if( !cache.dirty ) {
8978 return;
8979 }
8980
8981 std::uninitialized_fill_n( &cache.special[0][0], MAPSIZE_X * MAPSIZE_Y, PF_NORMAL );
8982
8983 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8984 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8985 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8986 if( !cur_submap ) {
8987 return;
8988 }
8989
8990 tripoint p( 0, 0, zlev );
8991
8992 for( int sx = 0; sx < SEEX; ++sx ) {
8993 p.x = sx + smx * SEEX;
8994 for( int sy = 0; sy < SEEY; ++sy ) {
8995 p.y = sy + smy * SEEY;
8996
8997 pf_special cur_value = PF_NORMAL;
8998
8999 maptile tile( cur_submap, point( sx, sy ) );
9000
9001 const auto &terrain = tile.get_ter_t();
9002 const auto &furniture = tile.get_furn_t();
9003 int part;
9004 const vehicle *veh = veh_at_internal( p, part );
9005
9006 const int cost = move_cost_internal( furniture, terrain, veh, part );
9007
9008 if( cost > 2 ) {
9009 cur_value |= PF_SLOW;
9010 } else if( cost <= 0 ) {
9011 cur_value |= PF_WALL;
9012 if( terrain.has_flag( TFLAG_CLIMBABLE ) ) {
9013 cur_value |= PF_CLIMBABLE;
9014 }
9015 }
9016
9017 if( veh != nullptr ) {
9018 cur_value |= PF_VEHICLE;
9019 }
9020
9021 for( const auto &fld : tile.get_field() ) {
9022 const field_entry &cur = fld.second;
9023 const field_type_id type = cur.get_field_type();
9024 const int field_intensity = cur.get_field_intensity();
9025 if( type.obj().get_dangerous( field_intensity - 1 ) ) {
9026 cur_value |= PF_FIELD;
9027 }
9028 }
9029
9030 if( !tile.get_trap_t().is_benign() || !terrain.trap.obj().is_benign() ) {
9031 cur_value |= PF_TRAP;
9032 }
9033
9034 if( terrain.has_flag( TFLAG_GOES_DOWN ) || terrain.has_flag( TFLAG_GOES_UP ) ||
9035 terrain.has_flag( TFLAG_RAMP ) || terrain.has_flag( TFLAG_RAMP_UP ) ||
9036 terrain.has_flag( TFLAG_RAMP_DOWN ) ) {
9037 cur_value |= PF_UPDOWN;
9038 }
9039
9040 if( terrain.has_flag( TFLAG_SHARP ) ) {
9041 cur_value |= PF_SHARP;
9042 }
9043
9044 cache.special[p.x][p.y] = cur_value;
9045 }
9046 }
9047 }
9048 }
9049
9050 cache.dirty = false;
9051}
@ TFLAG_CLIMBABLE
Definition: mapdata.h:307
@ TFLAG_SHARP
Definition: mapdata.h:296
pf_special
Definition: pathfinding.h:7
@ PF_NORMAL
Definition: pathfinding.h:8
@ PF_FIELD
Definition: pathfinding.h:12

References furniture, maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), get_pathfinding_cache(), get_submap_at_grid(), maptile::get_ter_t(), maptile::get_trap_t(), trap::is_benign(), MAPSIZE_X, MAPSIZE_Y, move_cost_internal(), my_MAPSIZE, PF_CLIMBABLE, PF_FIELD, PF_NORMAL, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, SEEX, SEEY, sx, sy, terrain, TFLAG_CLIMBABLE, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_SHARP, type, veh_at_internal(), tripoint::x, and tripoint::y.

Referenced by get_pathfinding_cache_ref().

◆ update_submap_active_item_status()

void map::update_submap_active_item_status ( const tripoint p)

Definition at line 5697 of file map.cpp.

5698{
5699 point l;
5700 submap *const current_submap = get_submap_at( p, l );
5701 if( current_submap->active_items.empty() ) {
5702 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
5703 }
5704}

References abs_sub, submap::active_items, active_item_cache::empty(), get_submap_at(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

◆ update_suspension_cache()

void map::update_suspension_cache ( const int &  z)

Definition at line 8175 of file map.cpp.

8176{
8177 level_cache &ch = get_cache( z );
8178 if( !ch.suspension_cache_dirty ) {
8179 return;
8180 }
8181 std::list<point> &suspension_cache = ch.suspension_cache;
8183 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8184 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8185 const submap *cur_submap = get_submap_at_grid( { smx, smy, z } );
8186
8187 if( cur_submap == nullptr ) {
8188 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", smx, smy,
8189 z );
8190 continue;
8191 }
8192
8193 for( int sx = 0; sx < SEEX; ++sx ) {
8194 for( int sy = 0; sy < SEEY; ++sy ) {
8195 point sp( sx, sy );
8196 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8197 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8198 tripoint loc( coords::project_combine( point_om_sm( point( smx, smy ) ), point_sm_ms( sp ) ).raw(),
8199 z );
8200 suspension_cache.emplace_back( getabs( loc ).xy() );
8201 }
8202 }
8203 }
8204 }
8205 }
8207 }
8208
8209 for( auto iter = suspension_cache.begin(); iter != suspension_cache.end(); ) {
8210 const point absp = *iter;
8211 const point locp = getlocal( absp );
8212 const tripoint loctp( locp, z );
8213 if( !inbounds( locp ) ) {
8214 ++iter;
8215 continue;
8216 }
8217 const submap *cur_submap = get_submap_at( loctp );
8218 if( cur_submap == nullptr ) {
8219 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", locp.x,
8220 locp.y, z );
8221 ++iter;
8222 continue;
8223 }
8224 const ter_t &terrain = ter( locp ).obj();
8225 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8226 if( !is_suspension_valid( loctp ) ) {
8227 support_dirty( loctp );
8228 iter = suspension_cache.erase( iter );
8229 } else {
8230 ++iter;
8231 }
8232 } else {
8233 iter = suspension_cache.erase( iter );
8234 }
8235 }
8236 ch.suspension_cache_dirty = false;
8237}
coords::coord_point< point, coords::origin::overmap, coords::sm > point_om_sm
Definition: coordinates.h:477
auto project_combine(const coord_point< PointL, CoarseOrigin, CoarseScale > &coarse, const coord_point< PointR, FineOrigin, FineScale > &fine)
Definition: coordinates.h:413
bool suspension_cache_initialized
Definition: map.h:310

References debugmsg, get_cache(), get_submap_at(), get_submap_at_grid(), submap::get_ter(), getabs(), getlocal(), inbounds(), is_suspension_valid(), my_MAPSIZE, int_id< T >::obj(), coords::project_combine(), SEEX, SEEY, support_dirty(), level_cache::suspension_cache, level_cache::suspension_cache_dirty, level_cache::suspension_cache_initialized, sx, sy, ter(), terrain, TFLAG_SUSPENDED, point::x, and point::y.

Referenced by build_map_cache().

◆ update_vehicle_cache()

void map::update_vehicle_cache ( vehicle ,
int  old_zlevel 
)

◆ update_vehicle_list()

void map::update_vehicle_list ( const submap to,
int  zlev 
)

Definition at line 399 of file map.cpp.

400{
401 // Update vehicle data
402 level_cache &ch = get_cache( zlev );
403 for( const auto &elem : to->vehicles ) {
404 ch.vehicle_list.insert( elem.get() );
405 if( !elem->loot_zones.empty() ) {
406 ch.zone_vehicles.insert( elem.get() );
407 }
408 }
409
411}

References get_cache(), last_full_vehicle_list_dirty, level_cache::vehicle_list, submap::vehicles, and level_cache::zone_vehicles.

Referenced by displace_vehicle(), editmap::mapgen_preview(), rotate(), shift(), and shift_vehicle_z().

◆ update_visibility_cache()

void map::update_visibility_cache ( int  zlev)

Definition at line 5706 of file map.cpp.

5707{
5708 visibility_variables_cache.variables_set = true; // Not used yet
5709 visibility_variables_cache.g_light_level = static_cast<int>( g->light_level( zlev ) );
5710 visibility_variables_cache.vision_threshold = g->u.get_vision_threshold(
5711 get_cache_ref( g->u.posz() ).lm[g->u.posx()][g->u.posy()].max() );
5712
5713 visibility_variables_cache.u_clairvoyance = g->u.clairvoyance();
5714 visibility_variables_cache.u_sight_impaired = g->u.sight_impaired();
5716
5717 int sm_squares_seen[MAPSIZE][MAPSIZE];
5718 std::memset( sm_squares_seen, 0, sizeof( sm_squares_seen ) );
5719
5720 int min_z = fov_3d ? -OVERMAP_DEPTH : zlev;
5721 int max_z = fov_3d ? OVERMAP_HEIGHT : zlev;
5722
5723 for( int z = min_z; z <= max_z; z++ ) {
5724
5725 auto &visibility_cache = get_cache( z ).visibility_cache;
5726
5727 tripoint p;
5728 p.z = z;
5729 int &x = p.x;
5730 int &y = p.y;
5731 for( x = 0; x < MAPSIZE_X; x++ ) {
5732 for( y = 0; y < MAPSIZE_Y; y++ ) {
5734 visibility_cache[x][y] = ll;
5735 if( z == zlev ) {
5736 sm_squares_seen[ x / SEEX ][ y / SEEY ] += ( ll == lit_level::BRIGHT || ll == lit_level::LIT );
5737 }
5738 }
5739 }
5740 }
5741
5742 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
5743 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
5744 if( sm_squares_seen[gridx][gridy] > 36 ) { // 25% of the submap is visible
5745 const tripoint sm( gridx, gridy, 0 );
5746 const auto abs_sm = map::abs_sub + sm;
5747 // TODO: fix point types
5748 const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sm ) );
5749 overmap_buffer.set_seen( abs_omt, true );
5750 }
5751 }
5752 }
5753}
lit_level apparent_light_at(const tripoint &p, const visibility_variables &cache) const
Determine the visible light level for a tile, based on light_at for the tile, vision distance,...
Definition: lightmap.cpp:764
void set_seen(const tripoint_abs_omt &p, bool seen=true)
static const efftype_id effect_boomered("boomered")
bool variables_set
Definition: map.h:122
bool u_sight_impaired
Definition: map.h:123

References abs_sub, apparent_light_at(), BRIGHT, effect_boomered, fov_3d, g, visibility_variables::g_light_level, get_cache(), get_cache_ref(), LIT, level_cache::lm, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, four_quadrants::max(), my_MAPSIZE, overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, overmapbuffer::set_seen(), coords::sm, sm_to_omt_copy(), visibility_variables::u_clairvoyance, visibility_variables::u_is_boomered, visibility_variables::u_sight_impaired, visibility_variables::variables_set, level_cache::visibility_cache, visibility_variables_cache, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw(), draw(), game::get_player_input(), and game::look_around().

◆ use_amount()

std::list< item > map::use_amount ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4917 of file map.cpp.

4919{
4920 std::list<item> ret;
4921 for( int radius = 0; radius <= range && quantity > 0; radius++ ) {
4922 for( const tripoint &p : points_in_radius( origin, radius ) ) {
4923 if( rl_dist( origin, p ) >= radius ) {
4924 std::list<item> tmp = use_amount_square( p, type, quantity, filter );
4925 ret.splice( ret.end(), tmp );
4926 }
4927 }
4928 }
4929 return ret;
4930}
std::list< item > use_amount_square(const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: map.cpp:4895

References points_in_radius(), cata::hash64_detail::ret, rl_dist(), type, and use_amount_square().

◆ use_amount_square()

std::list< item > map::use_amount_square ( const tripoint p,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4895 of file map.cpp.

4897{
4898 std::list<item> ret;
4899 // Handle infinite map sources.
4900 item water = water_from( p );
4901 if( water.typeId() == type ) {
4902 ret.push_back( water );
4903 quantity = 0;
4904 return ret;
4905 }
4906
4907 if( const std::optional<vpart_reference> vp = veh_at( p ).part_with_feature( "CARGO", true ) ) {
4908 std::list<item> tmp = use_amount_stack( vp->vehicle().get_items( vp->part_index() ), type,
4909 quantity, filter );
4910 ret.splice( ret.end(), tmp );
4911 }
4912 std::list<item> tmp = use_amount_stack( i_at( p ), type, quantity, filter );
4913 ret.splice( ret.end(), tmp );
4914 return ret;
4915}
item water_from(const tripoint &p)
Definition: map.cpp:4483
std::list< item > use_amount_stack(Stack stack, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4881

References i_at(), cata::hash64_detail::ret, type, item::typeId(), use_amount_stack(), veh_at(), and water_from().

Referenced by use_amount().

◆ use_charges()

std::list< item > map::use_charges ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item>,
basecamp bcp = nullptr 
)

Definition at line 5015 of file map.cpp.

5018{
5019 std::list<item> ret;
5020
5021 // populate a grid of spots that can be reached
5022 std::vector<tripoint> reachable_pts;
5023 reachable_flood_steps( reachable_pts, origin, range, 1, 100 );
5024
5025 // We prefer infinite map sources where available, so search for those
5026 // first
5027 for( const tripoint &p : reachable_pts ) {
5028 // Handle infinite map sources.
5029 item water = water_from( p );
5030 if( water.typeId() == type ) {
5031 water.charges = quantity;
5032 ret.push_back( water );
5033 quantity = 0;
5034 return ret;
5035 }
5036 }
5037
5038 if( bcp ) {
5039 ret = bcp->use_charges( type, quantity );
5040 if( quantity <= 0 ) {
5041 return ret;
5042 }
5043 }
5044
5045 for( const tripoint &p : reachable_pts ) {
5046 if( has_furn( p ) ) {
5047 use_charges_from_furn( furn( p ).obj(), type, quantity, this, p, ret, filter );
5048 if( quantity <= 0 ) {
5049 return ret;
5050 }
5051 }
5052
5053 if( accessible_items( p ) ) {
5054 std::list<item> tmp = use_charges_from_stack( i_at( p ), type, quantity, p, filter );
5055 ret.splice( ret.end(), tmp );
5056 if( quantity <= 0 ) {
5057 return ret;
5058 }
5059 }
5060
5061 const optional_vpart_position vp = veh_at( p );
5062 if( !vp ) {
5063 continue;
5064 }
5065
5066 const std::optional<vpart_reference> kpart = vp.part_with_feature( "FAUCET", true );
5067 const std::optional<vpart_reference> weldpart = vp.part_with_feature( "WELDRIG", true );
5068 const std::optional<vpart_reference> craftpart = vp.part_with_feature( "CRAFTRIG", true );
5069 const std::optional<vpart_reference> forgepart = vp.part_with_feature( "FORGE", true );
5070 const std::optional<vpart_reference> kilnpart = vp.part_with_feature( "KILN", true );
5071 const std::optional<vpart_reference> chempart = vp.part_with_feature( "CHEMLAB", true );
5072 const std::optional<vpart_reference> autoclavepart = vp.part_with_feature( "AUTOCLAVE", true );
5073 const std::optional<vpart_reference> cargo = vp.part_with_feature( "CARGO", true );
5074
5075 if( kpart ) { // we have a faucet, now to see what to drain
5076 itype_id ftype = itype_id::NULL_ID();
5077
5078 // Special case hotplates which draw battery power
5079 if( type == itype_hotplate ) {
5080 ftype = itype_battery;
5081 } else {
5082 ftype = type;
5083 }
5084
5085 // TODO: add a sane birthday arg
5087 tmp.charges = kpart->vehicle().drain( ftype, quantity );
5088 // TODO: Handle water poison when crafting starts respecting it
5089 quantity -= tmp.charges;
5090 ret.push_back( tmp );
5091
5092 if( quantity == 0 ) {
5093 return ret;
5094 }
5095 }
5096
5097 if( weldpart ) { // we have a weldrig, now to see what to drain
5098 itype_id ftype = itype_id::NULL_ID();
5099
5100 if( type == itype_welder ) {
5101 ftype = itype_battery;
5102 } else if( type == itype_soldering_iron ) {
5103 ftype = itype_battery;
5104 }
5105 // TODO: add a sane birthday arg
5107 tmp.charges = weldpart->vehicle().drain( ftype, quantity );
5108 quantity -= tmp.charges;
5109 ret.push_back( tmp );
5110
5111 if( quantity == 0 ) {
5112 return ret;
5113 }
5114 }
5115
5116 if( craftpart ) { // we have a craftrig, now to see what to drain
5117 itype_id ftype = itype_id::NULL_ID();
5118
5119 if( type == itype_press ) {
5120 ftype = itype_battery;
5121 } else if( type == itype_vac_sealer ) {
5122 ftype = itype_battery;
5123 } else if( type == itype_dehydrator ) {
5124 ftype = itype_battery;
5125 } else if( type == itype_food_processor ) {
5126 ftype = itype_battery;
5127 }
5128
5129 // TODO: add a sane birthday arg
5131 tmp.charges = craftpart->vehicle().drain( ftype, quantity );
5132 quantity -= tmp.charges;
5133 ret.push_back( tmp );
5134
5135 if( quantity == 0 ) {
5136 return ret;
5137 }
5138 }
5139
5140 if( forgepart ) { // we have a veh_forge, now to see what to drain
5141 itype_id ftype = itype_id::NULL_ID();
5142
5143 if( type == itype_forge ) {
5144 ftype = itype_battery;
5145 }
5146
5147 // TODO: add a sane birthday arg
5149 tmp.charges = forgepart->vehicle().drain( ftype, quantity );
5150 quantity -= tmp.charges;
5151 ret.push_back( tmp );
5152
5153 if( quantity == 0 ) {
5154 return ret;
5155 }
5156 }
5157
5158 if( kilnpart ) { // we have a veh_kiln, now to see what to drain
5159 itype_id ftype = itype_id::NULL_ID();
5160
5161 if( type == itype_kiln ) {
5162 ftype = itype_battery;
5163 }
5164
5165 // TODO: add a sane birthday arg
5167 tmp.charges = kilnpart->vehicle().drain( ftype, quantity );
5168 quantity -= tmp.charges;
5169 ret.push_back( tmp );
5170
5171 if( quantity == 0 ) {
5172 return ret;
5173 }
5174 }
5175
5176 if( chempart ) { // we have a chem_lab, now to see what to drain
5177 itype_id ftype = itype_id::NULL_ID();
5178
5179 if( type == itype_chemistry_set ) {
5180 ftype = itype_battery;
5181 } else if( type == itype_hotplate ) {
5182 ftype = itype_battery;
5183 } else if( type == itype_electrolysis_kit ) {
5184 ftype = itype_battery;
5185 }
5186
5187 // TODO: add a sane birthday arg
5189 tmp.charges = chempart->vehicle().drain( ftype, quantity );
5190 quantity -= tmp.charges;
5191 ret.push_back( tmp );
5192
5193 if( quantity == 0 ) {
5194 return ret;
5195 }
5196 }
5197
5198 if( autoclavepart ) { // we have an autoclave, now to see what to drain
5199 itype_id ftype = itype_id::NULL_ID();
5200
5201 if( type == itype_autoclave ) {
5202 ftype = itype_battery;
5203 }
5204
5205 // TODO: add a sane birthday arg
5207 tmp.charges = autoclavepart->vehicle().drain( ftype, quantity );
5208 quantity -= tmp.charges;
5209 ret.push_back( tmp );
5210
5211 if( quantity == 0 ) {
5212 return ret;
5213 }
5214 }
5215
5216 if( cargo ) {
5217 std::list<item> tmp =
5218 use_charges_from_stack( cargo->vehicle().get_items( cargo->part_index() ), type, quantity, p,
5219 filter );
5220 ret.splice( ret.end(), tmp );
5221 if( quantity <= 0 ) {
5222 return ret;
5223 }
5224 }
5225 }
5226
5227 return ret;
5228}
std::list< item > use_charges(const itype_id &fake_id, int &quantity)
Definition: basecamp.cpp:584
bool accessible_items(const tripoint &t) const
Check whether the player can access the items located .
Definition: map.cpp:6666
void reachable_flood_steps(std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
Populates a vector of points that are reachable within a number of steps from a point.
Definition: map.cpp:6395
static const itype_id itype_autoclave("autoclave")
static void use_charges_from_furn(const furn_t &f, const itype_id &type, int &quantity, map *m, const tripoint &p, std::list< item > &ret, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4947
static const itype_id itype_soldering_iron("soldering_iron")
static const itype_id itype_chemistry_set("chemistry_set")
std::list< item > use_charges_from_stack(Stack stack, const itype_id &type, int &quantity, const tripoint &pos, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4933
static const itype_id itype_press("press")
static const itype_id itype_hotplate("hotplate")
static const itype_id itype_electrolysis_kit("electrolysis_kit")
static const itype_id itype_food_processor("food_processor")
static const itype_id itype_forge("forge")
static const itype_id itype_battery("battery")
static const itype_id itype_dehydrator("dehydrator")
static const itype_id itype_kiln("kiln")
static const itype_id itype_welder("welder")
static const itype_id itype_vac_sealer("vac_sealer")

References accessible_items(), item::charges, furn(), has_furn(), i_at(), itype_autoclave, itype_battery, itype_chemistry_set, itype_dehydrator, itype_electrolysis_kit, itype_food_processor, itype_forge, itype_hotplate, itype_kiln, itype_press, itype_soldering_iron, itype_vac_sealer, itype_welder, string_id< itype >::NULL_ID(), optional_vpart_position::part_with_feature(), reachable_flood_steps(), cata::hash64_detail::ret, calendar::start_of_cataclysm, type, item::typeId(), basecamp::use_charges(), use_charges_from_furn(), use_charges_from_stack(), veh_at(), and water_from().

Referenced by basecamp_action_components::consume_components(), player::consume_items(), player::consume_tools(), Character::suffer_from_asthma(), and iexamine::use_furn_fake_item().

◆ valid_move()

bool map::valid_move ( const tripoint from,
const tripoint to,
bool  bash = false,
bool  flying = false,
bool  via_ramp = false 
) const

Returns true if a creature could walk from from to to in one step.

That is, if the tiles are adjacent and either on the same z-level or connected by stairs or (in case of flying monsters) open air with no floors.

Definition at line 1925 of file map.cpp.

1927{
1928 // Used to account for the fact that older versions of GCC can trip on the if statement here.
1929 assert( to.z > std::numeric_limits<int>::min() );
1930 // Note: no need to check inbounds here, because maptile_at will do that
1931 // If oob tile is supplied, the maptile_at will be an unpassable "null" tile
1932 if( std::abs( from.x - to.x ) > 1 || std::abs( from.y - to.y ) > 1 ||
1933 std::abs( from.z - to.z ) > 1 ) {
1934 return false;
1935 }
1936
1937 if( from.z == to.z ) {
1938 // But here we need to, to prevent bashing critters
1939 return passable( to ) || ( bash && inbounds( to ) );
1940 } else if( !zlevels ) {
1941 return false;
1942 }
1943
1944 const bool going_up = from.z < to.z;
1945
1946 const tripoint &up_p = going_up ? to : from;
1947 const tripoint &down_p = going_up ? from : to;
1948
1949 const maptile up = maptile_at( up_p );
1950 const ter_t &up_ter = up.get_ter_t();
1951 if( up_ter.id.is_null() ) {
1952 return false;
1953 }
1954 // Checking for ledge is a workaround for the case when mapgen doesn't
1955 // actually make a valid ledge drop location with zlevels on, this forces
1956 // at least one zlevel drop and if down_ter is impassible it's probably
1957 // inside a wall, we could workaround that further but it's unnecessary.
1958 const bool up_is_ledge = tr_at( up_p ).loadid == tr_ledge;
1959
1960 if( up_ter.movecost == 0 ) {
1961 // Unpassable tile
1962 return false;
1963 }
1964
1965 const maptile down = maptile_at( down_p );
1966 const ter_t &down_ter = down.get_ter_t();
1967 if( down_ter.id.is_null() ) {
1968 return false;
1969 }
1970
1971 if( !up_is_ledge && down_ter.movecost == 0 ) {
1972 // Unpassable tile
1973 return false;
1974 }
1975
1976 if( !up_ter.has_flag( TFLAG_NO_FLOOR ) && !up_ter.has_flag( TFLAG_GOES_DOWN ) && !up_is_ledge &&
1977 !via_ramp ) {
1978 // Can't move from up to down
1979 if( std::abs( from.x - to.x ) == 1 || std::abs( from.y - to.y ) == 1 ) {
1980 // Break the move into two - vertical then horizontal
1981 tripoint midpoint( down_p.xy(), up_p.z );
1982 return valid_move( down_p, midpoint, bash, flying, via_ramp ) &&
1983 valid_move( midpoint, up_p, bash, flying, via_ramp );
1984 }
1985 return false;
1986 }
1987
1988 if( !flying && !down_ter.has_flag( TFLAG_GOES_UP ) && !down_ter.has_flag( TFLAG_RAMP ) &&
1989 !up_is_ledge && !via_ramp ) {
1990 // Can't safely reach the lower tile
1991 return false;
1992 }
1993
1994 if( bash ) {
1995 return true;
1996 }
1997
1998 int part_up;
1999 const vehicle *veh_up = veh_at_internal( up_p, part_up );
2000 if( veh_up != nullptr ) {
2001 // TODO: Hatches below the vehicle, passable frames
2002 return false;
2003 }
2004
2005 int part_down;
2006 const vehicle *veh_down = veh_at_internal( down_p, part_down );
2007 if( veh_down != nullptr && veh_down->roof_at_part( part_down ) >= 0 ) {
2008 // TODO: OPEN (and only open) hatches from above
2009 return false;
2010 }
2011
2012 // Currently only furniture can block movement if everything else is OK
2013 // TODO: Vehicles with boards in the given spot
2014 return up.get_furn_t().movecost >= 0;
2015}
coords::coord_point< Point, Origin, Scale > midpoint(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:562
trap_id loadid
Definition: trap.h:88

References bash(), map_data_common_t::has_flag(), ter_t::id, inbounds(), string_id< T >::is_null(), trap::loadid, maptile_at(), midpoint(), map_data_common_t::movecost, passable(), vehicle::roof_at_part(), TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, tr_at(), tr_ledge, valid_move(), veh_at_internal(), tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by map_funcs::climbing_cost(), combined_movecost(), draw_critter_internal(), has_floor_or_support(), scent_map::inbounds(), iexamine::ledge(), explosion_handler::legacy_blast(), monster::move(), process_fields_in_submap(), route(), spread_gas(), monster::stumble(), and valid_move().

◆ veh_at() [1/2]

optional_vpart_position map::veh_at ( const tripoint p) const

Checks if tile is occupied by vehicle and by which part.

Parameters
pTile to check for vehicle

Definition at line 1073 of file map.cpp.

1074{
1075 if( !inbounds( p ) || !const_cast<map *>( this )->get_cache( p.z ).veh_in_active_range ) {
1076 return optional_vpart_position( std::nullopt );
1077 }
1078
1079 int part_num = 1;
1080 vehicle *const veh = const_cast<map *>( this )->veh_at_internal( p, part_num );
1081 if( !veh ) {
1082 return optional_vpart_position( std::nullopt );
1083 }
1084 return optional_vpart_position( vpart_position( *veh, part_num ) );
1085
1086}

References get_cache(), inbounds(), veh_at_internal(), level_cache::veh_in_active_range, and tripoint::z.

Referenced by Character::activate_bionic(), activity_on_turn_move_loot(), zone_manager::add(), add_splatter(), add_vehicle_to_map(), apply_faction_ownership(), are_requirements_nearby(), Creature::auto_find_hostile_target(), character_funcs::base_comfort_value(), bash(), bash_rating(), bash_vehicle(), board_vehicle(), build_seen_cache(), build_vision_transparency_cache(), VehicleSpawnFunction::builtin_parkinglot(), Character::burn_fuel(), can_do_activity_there(), can_examine_at(), can_interact_at(), can_pickup_at(), can_put_items(), can_use_bipod(), check_art_charge_req(), vehicle::autodrive_controller::check_drivable(), player::check_eligible_containers_for_crafting(), construct::check_empty(), vehicle::check_heli_ascend(), vehicle::check_heli_descend(), activity_handlers::chop_tree_finish(), climb_difficulty(), doors::close_door(), veh_interact::complete_vehicle(), game::control_vehicle(), coverage(), creature_in_field(), crush(), cycle_action(), debug_menu::debug(), deregister_vehicle_zone(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), game::do_turn(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_vehicle(), game::examine(), npc::execute_action(), ranged::expected_coverage(), fetch_activity(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_item(), Character::find_remote_fuel(), find_target_vehicle(), fire(), ranged::fire_gun(), game::fling_creature(), Character::floor_bedding_warmth(), Character::floor_item_warmth(), game::forced_door_closing(), inventory::form_from_map(), generic_multi_activity_check_requirement(), avatar::get_book_reader(), item::get_cable_target(), game::get_dangerous_tile(), player::get_eligible_containers_for_crafting(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), liquid_handler::get_liquid_target(), overmap_ui::get_overmap_path_to(), game::get_veh_dir_indicator_location(), grab(), game::grabbed_furn_move(), game::grabbed_veh_move(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), handbrake(), game::handle_action(), handle_action_menu(), Character::has_alarm_clock(), has_flag_vpart(), has_nearby_chair(), has_nearby_table(), jmapgen_setmap::has_vehicle_collision(), mapgen_function_json_base::has_vehicle_collision(), jmapgen_alternativly< PieceType >::has_vehicle_collision(), jmapgen_sign::has_vehicle_collision(), jmapgen_vending_machine::has_vehicle_collision(), jmapgen_toilet::has_vehicle_collision(), jmapgen_gaspump::has_vehicle_collision(), jmapgen_vehicle::has_vehicle_collision(), jmapgen_trap::has_vehicle_collision(), jmapgen_furniture::has_vehicle_collision(), jmapgen_terrain::has_vehicle_collision(), jmapgen_computer::has_vehicle_collision(), jmapgen_sealed_item::has_vehicle_collision(), Character::has_watch(), haul(), Character::in_climate_control(), advanced_inv_area::init(), is_bashable(), is_driving(), weather::is_sheltered(), Character::is_snuggling(), explosion_handler::legacy_blast(), explosion_handler::legacy_shrapnel(), game::load(), make_active(), mine_activity(), monster_in_field(), mop_spills(), avatar_action::move(), move_cost(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_helicopter(), obstacle_coverage(), obstacle_name(), open(), open_door(), vehicle::part_collision(), Character::passive_power_gen(), liquid_handler::perform_liquid_transfer(), game::phasing_move(), npc::pick_up_item(), game::place_player(), player_in_field(), pldrive(), game::print_all_tile_info(), item::process_cable(), item::process_extinguish(), explosion_handler::ExplosionProcess::project_shrapnel(), projectile_attack(), vehicle_part::properties_to_item(), put_into_vehicle_or_drop(), game::remoteveh(), DefaultRemovePartHandler::removed(), zone_manager::revert_vzones(), iexamine::rubble(), conditional_t< T >::set_is_driving(), set_item_map_or_vehicle(), shoot(), iexamine::shrub_wildveggies(), spell_effect::spawn_summoned_vehicle(), autodrive_activity_actor::start(), activity_handlers::start_engines_finish(), supports_above(), game::swap_critters(), avatar_action::swim(), rot::temperature_flag_for_location(), tidy_activity(), avatar_funcs::try_to_sleep(), unboard_vehicle(), Character::update_bodytemp(), editmap::update_view_with_help(), deploy_furn_actor::use(), deploy_tent_actor::use(), use_amount_square(), use_charges(), game::validate_linked_vehicles(), veh_at(), vehicle_activity(), activity_handlers::vehicle_finish(), vehicle_selector::vehicle_selector(), wait(), game::walk_move(), avatar_action::wield(), and workbench_crafting_speed_multiplier().

◆ veh_at() [2/2]

optional_vpart_position map::veh_at ( const tripoint_abs_ms p) const

Definition at line 1068 of file map.cpp.

1069{
1070 return veh_at( getlocal( p ) );
1071}

References getlocal(), and veh_at().

◆ veh_at_internal() [1/2]

vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
)

Definition at line 1108 of file map.cpp.

1109{
1110 return const_cast<vehicle *>( const_cast<const map *>( this )->veh_at_internal( p, part_num ) );
1111}

References veh_at_internal().

Referenced by draw_from_above(), draw_maptile(), process_fields_in_submap(), route(), update_pathfinding_cache(), valid_move(), veh_at(), and veh_at_internal().

◆ veh_at_internal() [2/2]

const vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
) const

Definition at line 1088 of file map.cpp.

1089{
1090 // This function is called A LOT. Move as much out of here as possible.
1091 const level_cache &ch = get_cache( p.z );
1092 if( !ch.veh_in_active_range || !ch.veh_exists_at[p.x][p.y] ) {
1093 part_num = -1;
1094 return nullptr; // Clear cache indicates no vehicle. This should optimize a great deal.
1095 }
1096
1097 const auto it = ch.veh_cached_parts.find( p );
1098 if( it != ch.veh_cached_parts.end() ) {
1099 part_num = it->second.second;
1100 return it->second.first;
1101 }
1102
1103 debugmsg( "vehicle part cache indicated vehicle not found: %d %d %d", p.x, p.y, p.z );
1104 part_num = -1;
1105 return nullptr;
1106}

References debugmsg, get_cache(), level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

◆ vehicle_vehicle_collision()

float map::vehicle_vehicle_collision ( vehicle veh,
vehicle veh2,
const std::vector< veh_collision > &  collisions 
)

Definition at line 821 of file map.cpp.

823{
824 if( &veh == &veh2 ) {
825 debugmsg( "Vehicle %s collided with itself", veh.name );
826 return 0.0f;
827 }
828
829 // Effects of colliding with another vehicle:
830 // transfers of momentum, skidding,
831 // parts are damaged/broken on both sides,
832 // remaining times are normalized
833 const veh_collision &c = collisions[0];
834 add_msg( m_bad, _( "The %1$s's %2$s collides with %3$s's %4$s." ),
835 veh.name, veh.part_info( c.part ).name(),
836 veh2.name, veh2.part_info( c.target_part ).name() );
837
838 const bool vertical = veh.sm_pos.z != veh2.sm_pos.z;
839
840 // Used to calculate the epicenter of the collision.
841 point epicenter1;
842 point epicenter2;
843
844 float dmg;
845 // Vertical collisions will be simpler for a while (1D)
846 if( !vertical ) {
847 // For reference, a cargo truck weighs ~25300, a bicycle 690,
848 // and 38mph is 3800 'velocity'
849 rl_vec2d velo_veh1 = veh.velo_vec();
850 rl_vec2d velo_veh2 = veh2.velo_vec();
851 const float m1 = to_kilogram( veh.total_mass() );
852 const float m2 = to_kilogram( veh2.total_mass() );
853 //Energy of vehicle1 and vehicle2 before collision
854 float E = 0.5 * m1 * velo_veh1.magnitude() * velo_veh1.magnitude() +
855 0.5 * m2 * velo_veh2.magnitude() * velo_veh2.magnitude();
856
857 // Collision_axis
858 point cof1 = veh .rotated_center_of_mass();
859 point cof2 = veh2.rotated_center_of_mass();
860 int &x_cof1 = cof1.x;
861 int &y_cof1 = cof1.y;
862 int &x_cof2 = cof2.x;
863 int &y_cof2 = cof2.y;
864 rl_vec2d collision_axis_y;
865
866 collision_axis_y.x = ( veh.global_pos3().x + x_cof1 ) - ( veh2.global_pos3().x + x_cof2 );
867 collision_axis_y.y = ( veh.global_pos3().y + y_cof1 ) - ( veh2.global_pos3().y + y_cof2 );
868 collision_axis_y = collision_axis_y.normalized();
869 rl_vec2d collision_axis_x = collision_axis_y.rotated( M_PI / 2 );
870 // imp? & delta? & final? reworked:
871 // newvel1 =( vel1 * ( mass1 - mass2 ) + ( 2 * mass2 * vel2 ) ) / ( mass1 + mass2 )
872 // as per http://en.wikipedia.org/wiki/Elastic_collision
873 //velocity of veh1 before collision in the direction of collision_axis_y
874 float vel1_y = collision_axis_y.dot_product( velo_veh1 );
875 float vel1_x = collision_axis_x.dot_product( velo_veh1 );
876 //velocity of veh2 before collision in the direction of collision_axis_y
877 float vel2_y = collision_axis_y.dot_product( velo_veh2 );
878 float vel2_x = collision_axis_x.dot_product( velo_veh2 );
879 // e = 0 -> inelastic collision
880 // e = 1 -> elastic collision
881 float e = get_collision_factor( vel1_y / 100 - vel2_y / 100 );
882
883 // Velocity after collision
884 // vel1_x_a = vel1_x, because in x-direction we have no transmission of force
885 float vel1_x_a = vel1_x;
886 float vel2_x_a = vel2_x;
887 // Transmission of force only in direction of collision_axix_y
888 // Equation: partially elastic collision
889 float vel1_y_a = ( m2 * vel2_y * ( 1 + e ) + vel1_y * ( m1 - m2 * e ) ) / ( m1 + m2 );
890 float vel2_y_a = ( m1 * vel1_y * ( 1 + e ) + vel2_y * ( m2 - m1 * e ) ) / ( m1 + m2 );
891 // Add both components; Note: collision_axis is normalized
892 rl_vec2d final1 = collision_axis_y * vel1_y_a + collision_axis_x * vel1_x_a;
893 rl_vec2d final2 = collision_axis_y * vel2_y_a + collision_axis_x * vel2_x_a;
894
895 veh.move.init( final1.as_point() );
896 if( final1.dot_product( veh.face_vec() ) < 0 ) {
897 // Car is being pushed backwards. Make it move backwards
898 veh.velocity = -final1.magnitude();
899 } else {
900 veh.velocity = final1.magnitude();
901 }
902
903 veh2.move.init( final2.as_point() );
904 if( final2.dot_product( veh2.face_vec() ) < 0 ) {
905 // Car is being pushed backwards. Make it move backwards
906 veh2.velocity = -final2.magnitude();
907 } else {
908 veh2.velocity = final2.magnitude();
909 }
910
911 //give veh2 the initiative to proceed next before veh1
912 float avg_of_turn = ( veh2.of_turn + veh.of_turn ) / 2;
913 if( avg_of_turn < .1f ) {
914 avg_of_turn = .1f;
915 }
916
917 veh.of_turn = avg_of_turn * .9;
918 veh2.of_turn = avg_of_turn * 1.1;
919
920 //Energy after collision
921 float E_a = 0.5 * m1 * final1.magnitude() * final1.magnitude() +
922 0.5 * m2 * final2.magnitude() * final2.magnitude();
923 float d_E = E - E_a; //Lost energy at collision -> deformation energy
924 dmg = std::abs( d_E / 1000 / 2000 ); //adjust to balance damage
925 } else {
926 const float m1 = to_kilogram( veh.total_mass() );
927 // Collision is perfectly inelastic for simplicity
928 // Assume veh2 is standing still
929 dmg = std::abs( veh.vertical_velocity / 100 ) * m1 / 10;
930 veh.vertical_velocity = 0;
931 }
932
933 float dmg_veh1 = dmg * 0.5;
934 float dmg_veh2 = dmg * 0.5;
935
936 int coll_parts_cnt = 0; //quantity of colliding parts between veh1 and veh2
937 for( const auto &veh_veh_coll : collisions ) {
938 if( &veh2 == static_cast<vehicle *>( veh_veh_coll.target ) ) {
939 coll_parts_cnt++;
940 }
941 }
942
943 const float dmg1_part = dmg_veh1 / coll_parts_cnt;
944 const float dmg2_part = dmg_veh2 / coll_parts_cnt;
945
946 //damage colliding parts (only veh1 and veh2 parts)
947 for( const auto &veh_veh_coll : collisions ) {
948 if( &veh2 != static_cast<vehicle *>( veh_veh_coll.target ) ) {
949 continue;
950 }
951
952 int parm1 = veh.part_with_feature( veh_veh_coll.part, VPFLAG_ARMOR, true );
953 if( parm1 < 0 ) {
954 parm1 = veh_veh_coll.part;
955 }
956 int parm2 = veh2.part_with_feature( veh_veh_coll.target_part, VPFLAG_ARMOR, true );
957 if( parm2 < 0 ) {
958 parm2 = veh_veh_coll.target_part;
959 }
960
961 epicenter1 += veh.part( parm1 ).mount;
962 veh.damage( parm1, dmg1_part, DT_BASH );
963
964 epicenter2 += veh2.part( parm2 ).mount;
965 veh2.damage( parm2, dmg2_part, DT_BASH );
966 }
967
968 epicenter2.x /= coll_parts_cnt;
969 epicenter2.y /= coll_parts_cnt;
970
971 if( dmg2_part > 100 ) {
972 // Shake vehicle because of collision
973 veh2.damage_all( dmg2_part / 2, dmg2_part, DT_BASH, epicenter2 );
974 }
975
976 if( dmg_veh1 > 800 ) {
977 veh.skidding = true;
978 }
979
980 if( dmg_veh2 > 800 ) {
981 veh2.skidding = true;
982 }
983
984 // Return the impulse of the collision
985 return dmg_veh1;
986}
point rotated_center_of_mass() const
Definition: vehicle.cpp:3328
rl_vec2d face_vec() const
rl_vec2d velo_vec() const
float of_turn
Definition: vehicle.h:1956
std::string name() const
Translated name of a part.
Definition: veh_type.cpp:700
#define M_PI
Definition: math_defines.h:21
point as_point() const
Definition: line.cpp:687
rl_vec2d rotated(float angle) const
Definition: line.cpp:648
float magnitude() const
Definition: line.cpp:611
rl_vec2d normalized() const
Definition: line.cpp:621
float y
Definition: point_float.h:13
float x
Definition: point_float.h:12
float dot_product(const rl_vec2d &v) const
Definition: line.cpp:665
@ VPFLAG_ARMOR
Definition: veh_type.h:32
float get_collision_factor(float delta_v)

References _, add_msg(), rl_vec2d::as_point(), c, vehicle::damage(), vehicle::damage_all(), debugmsg, rl_vec2d::dot_product(), DT_BASH, vehicle::face_vec(), get_collision_factor(), vehicle::global_pos3(), tileray::init(), m_bad, M_PI, rl_vec2d::magnitude(), vehicle_part::mount, vehicle::move, vpart_info::name(), vehicle::name, rl_vec2d::normalized(), vehicle::of_turn, vehicle::part(), vehicle::part_info(), vehicle::part_with_feature(), rl_vec2d::rotated(), vehicle::rotated_center_of_mass(), vehicle::skidding, vehicle::sm_pos, units::to_kilogram(), vehicle::total_mass(), vehicle::velo_vec(), vehicle::velocity, vehicle::vertical_velocity, VPFLAG_ARMOR, point::x, tripoint::x, rl_vec2d::x, point::y, tripoint::y, rl_vec2d::y, and tripoint::z.

Referenced by move_vehicle().

◆ vehicle_wheel_traction()

float map::vehicle_wheel_traction ( const vehicle veh,
bool  ignore_movement_modifiers = false 
) const

Definition at line 1586 of file vehicle_move.cpp.

1588{
1589 if( veh.is_in_water( true ) ) {
1590 return veh.can_float() ? 1.0f : -1.0f;
1591 }
1592 if( veh.is_in_water() && veh.is_watercraft() && veh.can_float() ) {
1593 return 1.0f;
1594 }
1595
1596 const auto &wheel_indices = veh.wheelcache;
1597 int num_wheels = wheel_indices.size();
1598 if( num_wheels == 0 ) {
1599 // TODO: Assume it is digging in dirt
1600 // TODO: Return something that could be reused for dragging
1601 return 0.0f;
1602 }
1603
1604 float traction_wheel_area = 0.0f;
1605
1606 if( vehicle_movement::is_on_rails( *this, veh ) ) {
1607 // Vehicles on rails are considered to have all of their wheels on rails
1608 for( int p : veh.rail_wheelcache ) {
1609 traction_wheel_area += veh.cpart( p ).wheel_area();
1610 }
1611 return traction_wheel_area;
1612 }
1613
1614 for( int p : wheel_indices ) {
1615 const tripoint &pp = veh.global_part_pos3( p );
1616 const int wheel_area = veh.cpart( p ).wheel_area();
1617
1618 const auto &tr = ter( pp ).obj();
1619 // Deep water and air
1620 if( tr.has_flag( TFLAG_DEEP_WATER ) || tr.has_flag( TFLAG_NO_FLOOR ) ) {
1621 // No traction from wheel in water or air
1622 continue;
1623 }
1624
1625 int move_mod = move_cost_ter_furn( pp );
1626 if( move_mod == 0 ) {
1627 // Vehicle locked in wall
1628 // Shouldn't happen, but does
1629 return 0.0f;
1630 }
1631
1632 for( const auto &terrain_mod : veh.part_info( p ).wheel_terrain_mod() ) {
1633 if( !tr.has_flag( terrain_mod.first ) ) {
1634 move_mod += terrain_mod.second;
1635 break;
1636 }
1637 }
1638
1639 // Ignore the movement modifier if needed.
1640 if( ignore_movement_modifiers ) {
1641 move_mod = 2;
1642 }
1643
1644 traction_wheel_area += 2.0 * wheel_area / move_mod;
1645 }
1646
1647 return traction_wheel_area;
1648}
bool is_watercraft() const
Definition: vehicle.cpp:4218
std::vector< int > rail_wheelcache
Definition: vehicle.h:1845
bool can_float() const
can_float does the vehicle have freeboard or does it overflow with water?
Definition: vehicle.cpp:4155
std::vector< std::pair< std::string, int > > wheel_terrain_mod() const
Definition: veh_type.cpp:898
bool is_on_rails(const map &m, const vehicle &veh)
Returns whether the vehicle is currently on rails.

References vehicle::can_float(), vehicle::cpart(), vehicle::global_part_pos3(), vehicle::is_in_water(), vehicle_movement::is_on_rails(), vehicle::is_watercraft(), move_cost_ter_furn(), int_id< T >::obj(), vehicle::part_info(), vehicle::rail_wheelcache, ter(), TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, vehicle_part::wheel_area(), vpart_info::wheel_terrain_mod(), and vehicle::wheelcache.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ vehmove()

void map::vehmove ( )

Definition at line 473 of file map.cpp.

474{
475 // give vehicles movement points
476 VehicleList vehicle_list;
477 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
478 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
479 for( int zlev = minz; zlev <= maxz; ++zlev ) {
480 level_cache &cache = get_cache( zlev );
481 for( vehicle *veh : cache.vehicle_list ) {
482 veh->gain_moves();
483 veh->slow_leak();
485 w.v = veh;
486 vehicle_list.push_back( w );
487 }
488 }
489
490 // 15 equals 3 >50mph vehicles, or up to 15 slow (1 square move) ones
491 // But 15 is too low for V12 death-bikes, let's put 100 here
492 for( int count = 0; count < 100; count++ ) {
493 if( !vehproceed( vehicle_list ) ) {
494 break;
495 }
496 }
497 // Process item removal on the vehicles that were modified this turn.
498 // Use a copy because part_removal_cleanup can modify the container.
499 auto temp = dirty_vehicle_list;
500 for( const auto &elem : temp ) {
501 auto same_ptr = [ elem ]( const struct wrapped_vehicle & tgt ) {
502 return elem == tgt.v;
503 };
504 if( std::find_if( vehicle_list.begin(), vehicle_list.end(), same_ptr ) !=
505 vehicle_list.end() ) {
506 elem->part_removal_cleanup();
507 }
508 }
509 dirty_vehicle_list.clear();
510 // The bool tracks whether the vehicles is on the map or not.
511 std::map<vehicle *, bool> connected_vehicles;
512 for( int zlev = minz; zlev <= maxz; ++zlev ) {
513 level_cache &cache = get_cache( zlev );
514 vehicle::enumerate_vehicles( connected_vehicles, cache.vehicle_list );
515 }
516 for( std::pair<vehicle *const, bool> &veh_pair : connected_vehicles ) {
517 veh_pair.first->idle( veh_pair.second );
518 }
519}
bool vehproceed(VehicleList &vehicle_list)
Definition: map.cpp:521
static void enumerate_vehicles(std::map< vehicle *, bool > &connected_vehicles, const std::set< vehicle * > &vehicle_list)
Use grid traversal to enumerate all connected vehicles.
Definition: vehicle.cpp:4929
void slow_leak()
Definition: vehicle.cpp:5296
void gain_moves()
Definition: vehicle.cpp:5543

References abs_sub, detail::count(), dirty_vehicle_list, vehicle::enumerate_vehicles(), vehicle::gain_moves(), get_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::slow_leak(), wrapped_vehicle::v, level_cache::vehicle_list, vehproceed(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ vehproceed()

bool map::vehproceed ( VehicleList vehicle_list)

Definition at line 521 of file map.cpp.

522{
523 wrapped_vehicle *cur_veh = nullptr;
524 float max_of_turn = 0;
525 // First horizontal movement
526 for( wrapped_vehicle &vehs_v : vehicle_list ) {
527 if( vehs_v.v->of_turn > max_of_turn ) {
528 cur_veh = &vehs_v;
529 max_of_turn = cur_veh->v->of_turn;
530 }
531 }
532
533 // Then vertical-only movement
534 if( cur_veh == nullptr ) {
535 for( wrapped_vehicle &vehs_v : vehicle_list ) {
536 if( vehs_v.v->is_falling || ( vehs_v.v->is_rotorcraft() && vehs_v.v->get_z_change() != 0 ) ) {
537 cur_veh = &vehs_v;
538 break;
539 }
540 }
541 }
542
543 if( cur_veh == nullptr ) {
544 return false;
545 }
546
547 cur_veh->v = cur_veh->v->act_on_map();
548 if( cur_veh->v == nullptr ) {
549 vehicle_list = get_vehicles();
550 }
551
552 // confirm that veh_in_active_range is still correct for each z-level
553 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
554 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
555 for( int zlev = minz; zlev <= maxz; ++zlev ) {
556 level_cache &cache = get_cache( zlev );
557
558 // Check if any vehicles exist in the active range for this z-level
560 std::any_of( std::begin( cache.veh_exists_at ),
561 std::end( cache.veh_exists_at ), []( const auto & row ) {
562 return std::any_of( std::begin( row ), std::end( row ), []( bool veh_exists ) {
563 return veh_exists;
564 } );
565 } );
566 }
567
568 return true;
569}
vehicle * act_on_map()

References abs_sub, vehicle::act_on_map(), get_cache(), get_vehicles(), vehicle::of_turn, OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::v, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by vehmove().

◆ vertical_shift()

void map::vertical_shift ( int  newz)

Moves the map vertically to (not by!) newz.

Does not actually shift anything, only forces cache updates. In the future, it will either actually shift the map or it will get removed after 3D migration is complete.

Definition at line 7020 of file map.cpp.

7021{
7022 if( !zlevels ) {
7023 debugmsg( "Called map::vertical_shift in a non-z-level world" );
7024 return;
7025 }
7026
7027 if( newz < -OVERMAP_DEPTH || newz > OVERMAP_HEIGHT ) {
7028 debugmsg( "Tried to get z-level %d outside allowed range of %d-%d",
7029 newz, -OVERMAP_DEPTH, OVERMAP_HEIGHT );
7030 return;
7031 }
7032
7033 tripoint trp = get_abs_sub();
7034 set_abs_sub( tripoint( trp.xy(), newz ) );
7035
7036 // TODO: Remove the function when it's safe
7037 return;
7038}

References debugmsg, get_abs_sub(), OVERMAP_DEPTH, OVERMAP_HEIGHT, set_abs_sub(), tripoint::xy(), and zlevels.

Referenced by game::vertical_shift().

◆ water_from()

item map::water_from ( const tripoint p)

Definition at line 4483 of file map.cpp.

4484{
4485 if( has_flag( "SALT_WATER", p ) ) {
4487 }
4488
4489 const ter_id terrain_id = ter( p );
4490 if( terrain_id == t_sewage ) {
4492 ret.poison = rng( 1, 7 );
4493 return ret;
4494 }
4495
4497 // iexamine::water_source requires a valid liquid from this function.
4498 if( terrain_id.obj().examine == &iexamine::water_source ) {
4499 int poison_chance = 0;
4500 if( terrain_id.obj().has_flag( TFLAG_DEEP_WATER ) ) {
4501 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4502 poison_chance = 20;
4503 } else {
4504 poison_chance = 4;
4505 }
4506 } else {
4507 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4508 poison_chance = 10;
4509 } else {
4510 poison_chance = 3;
4511 }
4512 }
4513 if( one_in( poison_chance ) ) {
4514 ret.poison = rng( 1, 4 );
4515 }
4516 return ret;
4517 }
4518 if( furn( p ).obj().examine == &iexamine::water_source ) {
4519 return ret;
4520 }
4521 return item();
4522}
static const int INFINITE_CHARGES
Definition: item.h:2155
void examine(Character &p, const tripoint &pos)
Calls the examine function of furniture or terrain at given tile, for given character.
Definition: map.cpp:1684
@ TFLAG_CURRENT
Definition: mapdata.h:302
void water_source(player &p, const tripoint &examp)
Definition: iexamine.cpp:3869

References examine(), map_data_common_t::examine, furn(), map_data_common_t::has_flag(), has_flag(), item::INFINITE_CHARGES, int_id< T >::obj(), one_in(), cata::hash64_detail::ret, rng(), calendar::start_of_cataclysm, t_sewage, ter(), TFLAG_CURRENT, TFLAG_DEEP_WATER, and iexamine::water_source().

Referenced by inventory::form_from_map(), use_amount_square(), use_charges(), and iexamine::water_source().

Friends And Related Function Documentation

◆ editmap

friend class editmap
friend

Definition at line 385 of file map.h.

◆ visitable< map_cursor >

friend class visitable< map_cursor >
friend

Definition at line 385 of file map.h.

Member Data Documentation

◆ abs_sub

tripoint map::abs_sub
protected

Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation).

It is set upon:

  • loading submap at grid[0],
  • generating submaps (generate)
  • shifting the map with shift

Definition at line 1796 of file map.h.

Referenced by add_item(), add_item_or_charges(), add_vehicle(), adjust_radiation(), apply_faction_ownership(), bash_rating(), bash_resistance(), bash_strength(), build_floor_caches(), can_put_items(), can_put_items_ter_furn(), check_submap_active_item_consistency(), clear_vehicle_cache(), create_anomaly(), decay_fields_and_scent(), detach_vehicle(), draw_fill_background(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), features(), furn(), furn_set(), furnname(), generate(), get_abs_sub(), get_active_items_in_radius(), get_nonant(), get_submap_at(), get_vehicles(), getabs(), getlocal(), has_flag(), has_flag_furn(), has_flag_ter(), has_flag_ter_or_furn(), has_furn(), i_at(), i_clear(), i_rem(), is_bashable(), is_bashable_furn(), is_bashable_ter(), is_bashable_ter_furn(), is_divable(), is_outside(), is_water_shallow_current(), loadn(), make_active(), move_cost(), move_cost_ter_furn(), name(), passable(), place_items(), place_npc(), place_vending(), points_on_zlevel(), process_fields(), process_fields_in_submap(), process_items(), reset_vehicle_cache(), rotate(), save(), saven(), scent_blockers(), set_abs_sub(), set_radiation(), set_temperature(), spawn_an_item(), spawn_item(), spawn_items(), spawn_monsters(), spawn_monsters_submap(), spawn_monsters_submap_group(), ter(), ter_set(), tername(), update_submap_active_item_status(), update_visibility_cache(), vehmove(), and vehproceed().

◆ caches

std::array< std::unique_ptr<level_cache>, OVERMAP_LAYERS > map::caches
private

Holds caches for visibility, light, transparency and vehicles.

Definition at line 1968 of file map.h.

Referenced by access_cache(), get_cache(), get_cache_ref(), and map().

◆ dirty_vehicle_list

◆ field_furn_locs

std::vector<tripoint> map::field_furn_locs
private

Vector of tripoints containing active field-emitting furniture.

Definition at line 1964 of file map.h.

Referenced by actualize(), furn_set(), get_furn_field_locations(), load(), and shift_traps().

◆ grid

std::vector<submap *> map::grid
private

The list of currently loaded submaps.

The size of this should not be changed. After calling load or generate, it should only contain non-null pointers. Use getsubmap or setsubmap to access it.

Definition at line 1953 of file map.h.

Referenced by actualize(), add_roofs(), clear_spawns(), clear_traps(), editmap::cleartmpmap(), displace_vehicle(), getsubmap(), loadn(), map(), saven(), and setsubmap().

◆ last_full_vehicle_list

VehicleList map::last_full_vehicle_list
private

Vehicle list doesn't change often, but is pretty expensive.

Definition at line 1984 of file map.h.

Referenced by get_vehicles().

◆ last_full_vehicle_list_dirty

bool map::last_full_vehicle_list_dirty = true
private

◆ max_populated_zlev

std::optional<std::pair<tripoint, int> > map::max_populated_zlev = std::nullopt
private

Definition at line 1998 of file map.h.

Referenced by calc_max_populated_zlev(), and invalidate_max_populated_zlev().

◆ my_MAPSIZE

◆ pathfinding_caches

std::array< std::unique_ptr<pathfinding_cache>, OVERMAP_LAYERS > map::pathfinding_caches
mutableprivate

Definition at line 1970 of file map.h.

Referenced by get_pathfinding_cache(), get_pathfinding_cache_ref(), and map().

◆ skew_vision_cache

lru_cache<point, char> map::skew_vision_cache
mutableprivate

Cache of coordinate pairs recently checked for visibility.

Definition at line 1979 of file map.h.

Referenced by build_map_cache(), and sees().

◆ submaps_with_active_items

std::set<tripoint> map::submaps_with_active_items
private

◆ support_cache_dirty

std::set<tripoint> map::support_cache_dirty
private

Definition at line 1494 of file map.h.

Referenced by process_falling(), shift(), support_dirty(), and ter_set().

◆ traplocs

std::vector< std::vector<tripoint> > map::traplocs
private

This vector contains an entry for each trap type, it has therefor the same size as the traplist vector.

Each entry contains a list of all point on the map that contain a trap of that type. The first entry however is always empty as it denotes the tr_null trap.

Definition at line 1960 of file map.h.

Referenced by actualize(), clear_traps(), load(), map(), remove_trap(), shift_traps(), ter_set(), trap_locations(), and trap_set().

◆ visibility_variables_cache

visibility_variables map::visibility_variables_cache
private

Definition at line 1994 of file map.h.

Referenced by get_visibility_variables_cache(), and update_visibility_cache().

◆ vision_transparency_cache

vision_adjustment map::vision_transparency_cache[8] = { VISION_ADJUST_NONE }
protected

Definition at line 1786 of file map.h.

Referenced by apply_vision_transparency_cache(), and build_vision_transparency_cache().

◆ zlevels


The documentation for this class was generated from the following files: